import html from './html.mjs'; import sql from './sql.mjs'; import css from './css.mjs'; import c from './c.mjs'; import javascript from './javascript.mjs'; import shellscript from './shellscript.mjs'; const lang = Object.freeze({ "displayName": "Crystal", "fileTypes": ["cr"], "firstLineMatch": "^#!/.*\\bcrystal", "foldingStartMarker": `(?x)^(\\s*+(annotation|module|class|struct|union|enum|def(?!.*\\bend\\s*$)|unless|if|case|begin|for|while|until|^=begin|("(\\\\.|[^"])*+"|'(\\\\.|[^'])*+'|[^#"'])*(\\s(do|begin|case)|(?~]\\s*+(if|unless)))\\b(?![^;]*+;.*?\\bend\\b)|("(\\\\.|[^"])*+"|'(\\\\.|[^'])*+'|[^#"'])*(\\{(?![^}]*+\\})|\\[(?![^\\]]*+\\]))).*$|[#].*?\\(fold\\)\\s*+$`, "foldingStopMarker": "(?x)((^|;)\\s*+end\\s*+([#].*)?$|(^|;)\\s*+end\\..*$|^\\s*+[}\\]] ,?\\s*+([#].*)?$|[#].*?\\(end\\)\\s*+$|^=end)", "name": "crystal", "patterns": [{ "captures": { "1": { "name": "keyword.control.class.crystal" }, "2": { "name": "keyword.control.class.crystal" }, "3": { "name": "entity.name.type.class.crystal" }, "5": { "name": "punctuation.separator.crystal" }, "6": { "name": "support.class.other.type-param.crystal" }, "7": { "name": "entity.other.inherited-class.crystal" }, "8": { "name": "punctuation.separator.crystal" }, "9": { "name": "punctuation.separator.crystal" }, "10": { "name": "support.class.other.type-param.crystal" }, "11": { "name": "punctuation.definition.variable.crystal" } }, "match": "(?x)^\\s*(abstract)?\\s*(class|struct|union|annotation|enum)\\s+(([.A-Z_:\\x{80}-\\x{10FFFF}][.\\w:\\x{80}-\\x{10FFFF}]*(\\(([,\\s.a-zA-Z0-9_:\\x{80}-\\x{10FFFF}]+)\\))?(\\s*(<)\\s*[.:A-Z\\x{80}-\\x{10FFFF}][.:\\w\\x{80}-\\x{10FFFF}]*(\\(([.a-zA-Z0-9_:]+\\s,)\\))?)?)|((<<)\\s*[.A-Z0-9_:\\x{80}-\\x{10FFFF}]+))", "name": "meta.class.crystal" }, { "captures": { "1": { "name": "keyword.control.module.crystal" }, "2": { "name": "entity.name.type.module.crystal" }, "3": { "name": "entity.other.inherited-class.module.first.crystal" }, "4": { "name": "punctuation.separator.inheritance.crystal" }, "5": { "name": "entity.other.inherited-class.module.second.crystal" }, "6": { "name": "punctuation.separator.inheritance.crystal" }, "7": { "name": "entity.other.inherited-class.module.third.crystal" }, "8": { "name": "punctuation.separator.inheritance.crystal" } }, "match": "^\\s*(module)\\s+(([A-Z\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*(::))?([A-Z\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*(::))?([A-Z\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*(::))*[A-Z\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*)", "name": "meta.module.crystal" }, { "captures": { "1": { "name": "keyword.control.lib.crystal" }, "2": { "name": "entity.name.type.lib.crystal" }, "3": { "name": "entity.other.inherited-class.lib.first.crystal" }, "4": { "name": "punctuation.separator.inheritance.crystal" }, "5": { "name": "entity.other.inherited-class.lib.second.crystal" }, "6": { "name": "punctuation.separator.inheritance.crystal" }, "7": { "name": "entity.other.inherited-class.lib.third.crystal" }, "8": { "name": "punctuation.separator.inheritance.crystal" } }, "match": "^\\s*(lib)\\s+(([A-Z]\\w*(::))?([A-Z]\\w*(::))?([A-Z]\\w*(::))*[A-Z]\\w*)", "name": "meta.lib.crystal" }, { "captures": { "1": { "name": "keyword.control.lib.type.crystal" }, "2": { "name": "entity.name.lib.type.crystal" }, "3": { "name": "keyword.control.lib.crystal" }, "4": { "name": "entity.name.lib.type.value.crystal" } }, "comment": "type in lib", "match": "(?|_|\\*|\\$|\\?|:|\"|-[0adFiIlpv])", "name": "variable.other.readwrite.global.pre-defined.crystal" }, { "begin": "\\b(ENV)\\[", "beginCaptures": { "1": { "name": "variable.other.constant.crystal" } }, "end": "\\]", "name": "meta.environment-variable.crystal", "patterns": [{ "include": "$self" }] }, { "comment": "Literals name of Crystal", "match": "\\b[A-Z\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*", "name": "support.class.crystal" }, { "comment": "Fetch from https://crystal-lang.org/api/0.36.1/toplevel.html", "match": "(?[a-zA-Z_]\\w*(?>\\.|::))? # method prefix\n (?> # method name\n [a-zA-Z_]\\w*(?>[?!]|=(?!>))?\n |\n \\^|===?|!=|>[>=]?|<=>|<[<=]?|[%&`/\\|]|\\*\\*?|=?~|[-+]@?|\\[][?=]?|\\[]=?\n )\n)\n\\s*(\\()", "beginCaptures": { "1": { "name": "keyword.control.def.crystal" }, "2": { "name": "entity.name.function.crystal" }, "3": { "name": "punctuation.definition.parameters.crystal" } }, "comment": "The method pattern comes from the symbol pattern. See there for an explanation.", "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.parameters.crystal" } }, "name": "meta.function.method.with-arguments.crystal", "patterns": [{ "begin": "(?![\\s,)])", "end": "(?=,|\\)\\s*$)", "patterns": [{ "captures": { "1": { "name": "storage.type.variable.crystal" }, "2": { "name": "constant.other.symbol.hashkey.parameter.function.crystal" }, "3": { "name": "punctuation.definition.constant.hashkey.crystal" }, "4": { "name": "variable.parameter.function.crystal" } }, "match": "\\G([&*]?)(?:([_a-zA-Z]\\w*(:))|([_a-zA-Z]\\w*))" }, { "include": "$self" }] }] }, { "captures": { "1": { "name": "keyword.control.def.crystal" }, "3": { "name": "entity.name.function.crystal" } }, "comment": " the optional name is just to catch the def also without a method-name", "match": "(?x)\n(?=def\\b) # optimization to help Oniguruma fail fast\n(?<=^|\\s)(def)\\b\n(\n \\s+\n (\n (?>[a-zA-Z_]\\w*(?>\\.|::))? # method prefix\n (?> # method name\n [a-zA-Z_]\\w*(?>[?!]|=(?!>))?\n |\n \\^|===?|!=|>[>=]?|<=>|<[<=]?|[%&`/\\|]|\\*\\*?|=?~|[-+]@?|\\[][?=]?|\\[]=?\n )\n )\n)?", "name": "meta.function.method.without-arguments.crystal" }, { "comment": "Floating point literal (fraction)", "match": "\\b[0-9][0-9_]*\\.[0-9][0-9_]*([eE][+-]?[0-9_]+)?(f32|f64)?\\b", "name": "constant.numeric.float.crystal" }, { "comment": "Floating point literal (exponent)", "match": "\\b[0-9][0-9_]*(\\.[0-9][0-9_]*)?[eE][+-]?[0-9_]+(f32|f64)?\\b", "name": "constant.numeric.float.crystal" }, { "comment": "Floating point literal (typed)", "match": "\\b[0-9][0-9_]*(\\.[0-9][0-9_]*)?([eE][+-]?[0-9_]+)?(f32|f64)\\b", "name": "constant.numeric.float.crystal" }, { "comment": "Integer literal (decimal)", "match": "\\b(?!0[0-9])[0-9][0-9_]*([ui](8|16|32|64|128))?\\b", "name": "constant.numeric.integer.decimal.crystal" }, { "comment": "Integer literal (hexadecimal)", "match": "\\b0x[a-fA-F0-9_]+([ui](8|16|32|64|128))?\\b", "name": "constant.numeric.integer.hexadecimal.crystal" }, { "comment": "Integer literal (octal)", "match": "\\b0o[0-7_]+([ui](8|16|32|64|128))?\\b", "name": "constant.numeric.integer.octal.crystal" }, { "comment": "Integer literal (binary)", "match": "\\b0b[01_]+([ui](8|16|32|64|128))?\\b", "name": "constant.numeric.integer.binary.crystal" }, { "begin": ":'", "beginCaptures": { "0": { "name": "punctuation.definition.symbol.begin.crystal" } }, "comment": "symbol literal with '' delimiter", "end": "'", "endCaptures": { "0": { "name": "punctuation.definition.symbol.end.crystal" } }, "name": "constant.other.symbol.crystal", "patterns": [{ "match": "\\\\['\\\\]", "name": "constant.character.escape.crystal" }] }, { "begin": ':"', "beginCaptures": { "0": { "name": "punctuation.section.symbol.begin.crystal" } }, "comment": 'symbol literal with "" delimiter', "end": '"', "endCaptures": { "0": { "name": "punctuation.section.symbol.end.crystal" } }, "name": "constant.other.symbol.interpolated.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "comment": "Needs higher precedence than regular expressions.", "match": "(?", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.interpolated.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_ltgt_i" }] }, { "begin": "%x\\(", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "execute string (allow for interpolation)", "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.interpolated.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_parens_i" }] }, { "begin": "%x\\|", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "execute string (allow for interpolation)", "end": "\\|", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.interpolated.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?x) (?: ^| (?<=[=>~(?:\\[,|&;] | [\\s;]if\\s| [\\s;]elsif\\s | [\\s;]while\\s | [\\s;]unless\\s | [\\s;]when\\s | [\\s;]assert_match\\s | [\\s;]or\\s| [\\s;]and\\s | [\\s;]not\\s | [\\s.]index\\s| [\\s.]scan\\s | [\\s.]sub\\s | [\\s.]sub!\\s | [\\s.]gsub\\s | [\\s.]gsub!\\s | [\\s.]match\\s ) | (?<=^when\\s| ^if\\s | ^elsif\\s | ^while\\s | ^unless\\s ) ) \\s*((/))(?![*+{}?])", "captures": { "1": { "name": "string.regexp.classic.crystal" }, "2": { "name": "punctuation.definition.string.crystal" } }, "comment": "regular expressions (normal) we only start a regexp if the character before it (excluding whitespace) is what we think is before a regexp", "contentName": "string.regexp.classic.crystal", "end": "((/[imsx]*))", "patterns": [{ "include": "#regex_sub" }] }, { "begin": "%r\\{", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "regular expressions (literal)", "end": "\\}[imsx]*", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.regexp.mod-r.crystal", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_curly_r" }] }, { "begin": "%r\\[", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "regular expressions (literal)", "end": "\\][imsx]*", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.regexp.mod-r.crystal", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_brackets_r" }] }, { "begin": "%r\\(", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "regular expressions (literal)", "end": "\\)[imsx]*", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.regexp.mod-r.crystal", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_parens_r" }] }, { "begin": "%r\\<", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "regular expressions (literal)", "end": "\\>[imsx]*", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.regexp.mod-r.crystal", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_ltgt_r" }] }, { "begin": "%r\\|", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "regular expressions (literal)", "end": "\\|[imsx]*", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.regexp.mod-r.crystal", "patterns": [{ "include": "#regex_sub" }] }, { "begin": "%Q?\\(", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal capable of interpolation ()", "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.upper.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_parens_i" }] }, { "begin": "%Q?\\[", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal capable of interpolation []", "end": "\\]", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.upper.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_brackets_i" }] }, { "begin": "%Q?\\<", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal capable of interpolation <>", "end": "\\>", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.upper.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_ltgt_i" }] }, { "begin": "%Q?\\{", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal capable of interpolation -- {}", "end": "\\}", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.double.crystal.mod", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_curly_i" }] }, { "begin": "%Q\\|", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal capable of interpolation -- ||", "end": "\\|", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.upper.crystal", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "%[qwi]\\(", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal incapable of interpolation -- ()", "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.lower.crystal", "patterns": [{ "match": "\\\\\\)|\\\\\\\\", "name": "constant.character.escape.crystal" }, { "include": "#nest_parens" }] }, { "begin": "%[qwi]\\<", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal incapable of interpolation -- <>", "end": "\\>", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.lower.crystal", "patterns": [{ "match": "\\\\\\>|\\\\\\\\", "name": "constant.character.escape.crystal" }, { "include": "#nest_ltgt" }] }, { "begin": "%[qwi]\\[", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal incapable of interpolation -- []", "end": "\\]", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.lower.crystal", "patterns": [{ "match": "\\\\\\]|\\\\\\\\", "name": "constant.character.escape.crystal" }, { "include": "#nest_brackets" }] }, { "begin": "%[qwi]\\{", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal incapable of interpolation -- {}", "end": "\\}", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.lower.crystal", "patterns": [{ "match": "\\\\\\}|\\\\\\\\", "name": "constant.character.escape.crystal" }, { "include": "#nest_curly" }] }, { "begin": "%[qwi]\\|", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "literal incapable of interpolation -- ||", "end": "\\|", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.quoted.other.literal.lower.crystal", "patterns": [{ "comment": "Cant be named because its not necessarily an escape.", "match": "\\\\." }] }, { "captures": { "1": { "name": "punctuation.definition.constant.crystal" } }, "comment": "symbols", "match": "(?[a-zA-Z_\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*(?>[?!]|=(?![>=]))?|===?|>[>=]?|<[<=]?|<=>|[%&`/\\|]|\\*\\*?|=?~|[-+]@?|\\[\\][?=]?|@@?[a-zA-Z_\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*)", "name": "constant.other.symbol.crystal" }, { "captures": { "1": { "name": "punctuation.definition.constant.crystal" } }, "comment": "symbols", "match": "(?>[a-zA-Z_\\x{80}-\\x{10FFFF}][\\w\\x{80}-\\x{10FFFF}]*(?>[?!])?)(:)(?!:)", "name": "constant.other.symbol.crystal.19syntax" }, { "captures": { "1": { "name": "punctuation.definition.comment.crystal" } }, "match": "(?:^[ \\t]+)?(#).*$\\n?", "name": "comment.line.number-sign.crystal" }, { "match": "\\b_([\\w]+[?!]?)", "name": "comment.unused.crystal" }, { "begin": "(?><<-('?)((?:[_\\w]+_|)HTML)\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded HTML and indented terminator", "contentName": "text.html.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.html.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "text.html.basic" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)SQL)\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded SQL and indented terminator", "contentName": "text.sql.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.sql.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.sql" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)CSS)\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded css and intented terminator", "contentName": "text.css.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.css.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.css" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)CPP)\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded c++ and intented terminator", "contentName": "text.c++.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.cplusplus.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.c++" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)C)\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded c++ and intented terminator", "contentName": "text.c.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.c.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.c" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)(?:JS|JAVASCRIPT))\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded javascript and intented terminator", "contentName": "text.js.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.js.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.js" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)JQUERY)\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded javascript and intented terminator", "contentName": "text.js.jquery.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.js.jquery.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.js.jquery" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)(?:SH|SHELL))\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded shell and intented terminator", "contentName": "text.shell.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.shell.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.shell" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-('?)((?:[_\\w]+_|)CRYSTAL)\\b\\1)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with embedded crystal and intented terminator", "contentName": "text.crystal.embedded.crystal", "end": "\\s*\\2\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.embedded.crystal.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "source.crystal" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-'(\\w+)')", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with indented terminator", "end": "\\s*\\1\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.heredoc.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "#escaped_char" }] }, { "begin": "(?><<-(\\w+)\\b)", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.crystal" } }, "comment": "heredoc with indented terminator", "end": "\\s*\\1\\b", "endCaptures": { "0": { "name": "punctuation.definition.string.end.crystal" } }, "name": "string.unquoted.heredoc.crystal", "patterns": [{ "include": "#heredoc" }, { "include": "#interpolated_crystal" }, { "include": "#escaped_char" }] }, { "begin": "(?<={|{\\s|[^A-Za-z0-9_]do|^do|[^A-Za-z0-9_]do\\s|^do\\s)(\\|)", "captures": { "1": { "name": "punctuation.separator.variable.crystal" } }, "end": "(?", "name": "punctuation.separator.key-value" }, { "match": "->", "name": "support.function.kernel.crystal" }, { "match": "<<=|%=|&{1,2}=|\\*=|\\*\\*=|\\+=|-=|\\^=|\\|{1,2}=|<<", "name": "keyword.operator.assignment.augmented.crystal" }, { "match": "<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|(?<=[ \\t])\\?", "name": "keyword.operator.comparison.crystal" }, { "match": "(?<=^|[ \\t])!|&&|\\|\\||\\^", "name": "keyword.operator.logical.crystal" }, { "match": "(\\{\\%|\\%\\}|\\{\\{|\\}\\})", "name": "keyword.operator.macro.crystal" }, { "captures": { "1": { "name": "punctuation.separator.method.crystal" } }, "comment": "Safe navigation operator", "match": "(&\\.)\\s*(?![A-Z])" }, { "match": "(%|&|\\*\\*|\\*|\\+|\\-|/)", "name": "keyword.operator.arithmetic.crystal" }, { "match": "=", "name": "keyword.operator.assignment.crystal" }, { "match": "\\||~|>>", "name": "keyword.operator.other.crystal" }, { "match": ":", "name": "punctuation.separator.other.crystal" }, { "match": "\\;", "name": "punctuation.separator.statement.crystal" }, { "match": ",", "name": "punctuation.separator.object.crystal" }, { "match": "\\.|::", "name": "punctuation.separator.method.crystal" }, { "match": "\\{|\\}", "name": "punctuation.section.scope.crystal" }, { "match": "\\[|\\]", "name": "punctuation.section.array.crystal" }, { "match": "\\(|\\)", "name": "punctuation.section.function.crystal" }, { "begin": "(?=[a-zA-Z0-9_!?]+\\()", "end": "(?<=\\))", "name": "meta.function-call.crystal", "patterns": [{ "match": "([a-zA-Z0-9_!?]+)(?=\\()", "name": "entity.name.function.crystal" }, { "include": "$self" }] }, { "comment": "This is kindof experimental. There really is no way to perfectly match all regular variables, but you can pretty well assume that any normal word in certain curcumstances that havnt already been scoped as something else are probably variables, and the advantages beat the potential errors", "match": "((?<=\\W)\\b|^)\\w+\\b(?=\\s*([\\]\\)\\}\\=\\+\\-\\*\\/\\^\\$\\,\\.]|<\\s|<<[\\s|\\.]))", "name": "variable.other.crystal" }], "repository": { "escaped_char": { "comment": "https://crystal-lang.org/reference/syntax_and_semantics/literals/string.html", "match": "\\\\(?:[0-7]{1,3}|x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|u\\{[a-fA-F0-9 ]+\\}|.)", "name": "constant.character.escape.crystal" }, "heredoc": { "begin": "^<<-?\\w+", "end": "$", "patterns": [{ "include": "$self" }] }, "interpolated_crystal": { "patterns": [{ "begin": "#\\{", "beginCaptures": { "0": { "name": "punctuation.section.embedded.begin.crystal" } }, "contentName": "source.crystal", "end": "(\\})", "endCaptures": { "0": { "name": "punctuation.section.embedded.end.crystal" }, "1": { "name": "source.crystal" } }, "name": "meta.embedded.line.crystal", "patterns": [{ "include": "#nest_curly_and_self" }, { "include": "$self" }], "repository": { "nest_curly_and_self": { "patterns": [{ "begin": "\\{", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\}", "patterns": [{ "include": "#nest_curly_and_self" }] }, { "include": "$self" }] } } }, { "captures": { "1": { "name": "punctuation.definition.variable.crystal" } }, "match": "(#@)[a-zA-Z_]\\w*", "name": "variable.other.readwrite.instance.crystal" }, { "captures": { "1": { "name": "punctuation.definition.variable.crystal" } }, "match": "(#@@)[a-zA-Z_]\\w*", "name": "variable.other.readwrite.class.crystal" }, { "captures": { "1": { "name": "punctuation.definition.variable.crystal" } }, "match": "(#\\$)[a-zA-Z_]\\w*", "name": "variable.other.readwrite.global.crystal" }] }, "nest_brackets": { "begin": "\\[", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\]", "patterns": [{ "include": "#nest_brackets" }] }, "nest_brackets_i": { "begin": "\\[", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\]", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_brackets_i" }] }, "nest_brackets_r": { "begin": "\\[", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\]", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_brackets_r" }] }, "nest_curly": { "begin": "\\{", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\}", "patterns": [{ "include": "#nest_curly" }] }, "nest_curly_and_self": { "patterns": [{ "begin": "\\{", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\}", "patterns": [{ "include": "#nest_curly_and_self" }] }, { "include": "$self" }] }, "nest_curly_i": { "begin": "\\{", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\}", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_curly_i" }] }, "nest_curly_r": { "begin": "\\{", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\}", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_curly_r" }] }, "nest_ltgt": { "begin": "\\<", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\>", "patterns": [{ "include": "#nest_ltgt" }] }, "nest_ltgt_i": { "begin": "\\<", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\>", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_ltgt_i" }] }, "nest_ltgt_r": { "begin": "\\<", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\>", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_ltgt_r" }] }, "nest_parens": { "begin": "\\(", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\)", "patterns": [{ "include": "#nest_parens" }] }, "nest_parens_i": { "begin": "\\(", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\)", "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "include": "#nest_parens_i" }] }, "nest_parens_r": { "begin": "\\(", "captures": { "0": { "name": "punctuation.section.scope.crystal" } }, "end": "\\)", "patterns": [{ "include": "#regex_sub" }, { "include": "#nest_parens_r" }] }, "regex_sub": { "patterns": [{ "include": "#interpolated_crystal" }, { "include": "#escaped_char" }, { "captures": { "1": { "name": "punctuation.definition.arbitrary-repetition.crystal" }, "3": { "name": "punctuation.definition.arbitrary-repetition.crystal" } }, "match": "({)\\d+(,\\d+)?(})", "name": "string.regexp.arbitrary-repetition.crystal" }, { "begin": "\\[(?:\\^?])?", "captures": { "0": { "name": "punctuation.definition.character-class.crystal" } }, "end": "]", "name": "string.regexp.character-class.crystal", "patterns": [{ "include": "#escaped_char" }] }, { "begin": "\\(", "captures": { "0": { "name": "punctuation.definition.group.crystal" } }, "end": "\\)", "name": "string.regexp.group.crystal", "patterns": [{ "include": "#regex_sub" }] }, { "captures": { "1": { "name": "punctuation.definition.comment.crystal" } }, "comment": "We are restrictive in what we allow to go after the comment character to avoid false positives, since the availability of comments depend on regexp flags.", "match": "(?<=^|\\s)(#)\\s[[a-zA-Z0-9,. \\t?!-][^\\x{00}-\\x{7F}]]*$", "name": "comment.line.number-sign.crystal" }] } }, "scopeName": "source.crystal", "embeddedLangs": ["html", "sql", "css", "c", "javascript", "shellscript"] }); var crystal = [ ...html, ...sql, ...css, ...c, ...javascript, ...shellscript, lang ]; export { crystal as default };