diff --git a/editors/vscode/package.json b/editors/vscode/package.json index 7b52eced..ec09530f 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -105,7 +105,7 @@ "languages": [ { "id": "typst", - "configuration": "./language-configuration.json", + "configuration": "./syntaxes/typst.language-configuration.json", "extensions": [ ".typ" ], @@ -118,6 +118,13 @@ } } ], + "grammars": [ + { + "language": "typst", + "scopeName": "source.typst", + "path": "./syntaxes/typst.tmLanguage.json" + } + ], "semanticTokenTypes": [ { "id": "bool", diff --git a/editors/vscode/language-configuration.json b/editors/vscode/syntaxes/typst.language-configuration.json similarity index 81% rename from editors/vscode/language-configuration.json rename to editors/vscode/syntaxes/typst.language-configuration.json index c3db14bb..72388604 100644 --- a/editors/vscode/language-configuration.json +++ b/editors/vscode/syntaxes/typst.language-configuration.json @@ -21,6 +21,7 @@ "open": "(", "close": ")" }, + { "open": "/*", "close": " */" }, { "open": "\"", "close": "\"", @@ -30,9 +31,14 @@ "open": "$", "close": "$", "notIn": ["string"] + }, + { + "open": "`", + "close": "`", + "notIn": ["string"] } ], - "autoCloseBefore": "$ \n\t", + "autoCloseBefore": ";:.,=}])>$ \n\t", "surroundingPairs": [ ["[", "]"], ["{", "}"], diff --git a/editors/vscode/syntaxes/typst.tmLanguage.json b/editors/vscode/syntaxes/typst.tmLanguage.json new file mode 100644 index 00000000..3a9743e1 --- /dev/null +++ b/editors/vscode/syntaxes/typst.tmLanguage.json @@ -0,0 +1,2650 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "typst", + "patterns": [ + { + "include": "#markup" + } + ], + "repository": { + "comments": { + "patterns": [ + { + "name": "comment.block.typst", + "begin": "/\\*", + "end": "\\*/", + "captures": { + "0": { + "name": "punctuation.definition.comment.typst" + } + }, + "patterns": [ + { + "include": "#comments" + } + ] + }, + { + "name": "comment.line.double-slash.typst", + "begin": "(?", + "captures": { + "1": { + "name": "punctuation.definition.label.typst" + } + } + }, + { + "name": "entity.other.reference.typst", + "match": "(@)[[:alpha:]_][[:alnum:]_-]*", + "captures": { + "1": { + "name": "punctuation.definition.reference.typst" + } + } + }, + { + "begin": "(#)(let|set|show)\\b", + "end": "\n|(;)|(?=])", + "beginCaptures": { + "0": { + "name": "keyword.other.typst" + }, + "1": { + "name": "punctuation.definition.keyword.typst" + } + }, + "endCaptures": { + "1": { + "name": "punctuation.terminator.statement.typst" + } + }, + "patterns": [ + { + "include": "#code" + } + ] + }, + { + "name": "keyword.other.typst", + "match": "(#)(as|in)\\b", + "captures": { + "1": { + "name": "punctuation.definition.keyword.typst" + } + } + }, + { + "begin": "(?:(#)if|(?:}(?:\\s*)|](?:\\s*))else)\\b", + "end": "\n|(?=])|(?<=}|])", + "beginCaptures": { + "0": { + "name": "keyword.control.conditional.typst" + }, + "2": { + "name": "punctuation.definition.keyword.typst" + } + }, + "patterns": [ + { + "include": "#code" + } + ] + }, + { + "begin": "(#)(for|while)\\b", + "end": "\n|(?=])|(?<=}|])", + "beginCaptures": { + "0": { + "name": "keyword.control.loop.typst" + }, + "1": { + "name": "punctuation.definition.keyword.typst" + } + }, + "patterns": [ + { + "include": "#code" + } + ] + }, + { + "name": "keyword.control.loop.typst", + "match": "(#)(break|continue)\\b", + "captures": { + "1": { + "name": "punctuation.definition.keyword.typst" + } + } + }, + { + "begin": "(#)(import|include|export)\\b", + "end": "\n|(;)|(?=])", + "beginCaptures": { + "0": { + "name": "keyword.control.import.typst" + }, + "1": { + "name": "punctuation.definition.keyword.typst" + } + }, + "endCaptures": { + "1": { + "name": "punctuation.terminator.statement.typst" + } + }, + "patterns": [ + { + "include": "#code" + } + ] + }, + { + "name": "keyword.control.flow.typst", + "match": "(#)(return)\\b", + "captures": { + "1": { + "name": "punctuation.definition.keyword.typst" + } + } + }, + { + "comment": "Function name", + "name": "entity.name.function.typst", + "match": "((#)[[:alpha:]_][[:alnum:]_-]*!?)(?=\\[|\\()", + "captures": { + "2": { + "name": "punctuation.definition.function.typst" + } + } + }, + { + "comment": "Function arguments", + "begin": "(?:#)([[A-Za-z]_][[0-9]_-]*!?(?=\\())\\(", + "end": "\\)", + "captures": { + "0": { + "name": "punctuation.definition.group.typst" + } + }, + "patterns": [ + { + "include": "#arguments" + } + ] + }, + { + "name": "entity.other.interpolated.typst", + "match": "(#)[[:alpha:]_][.[:alnum:]_-]*", + "captures": { + "1": { + "name": "punctuation.definition.variable.typst" + } + } + }, + { + "name": "meta.block.content.typst", + "begin": "#", + "end": "\\s", + "patterns": [ + { + "include": "#code" + } + ] + } + ] + }, + "code": { + "patterns": [ + { + "include": "#common" + }, + { + "name": "meta.block.code.typst", + "begin": "{", + "end": "}", + "captures": { + "0": { + "name": "punctuation.definition.block.code.typst" + } + }, + "patterns": [ + { + "include": "#code" + } + ] + }, + { + "name": "meta.block.content.typst", + "begin": "\\[", + "end": "\\]", + "captures": { + "0": { + "name": "punctuation.definition.block.content.typst" + } + }, + "patterns": [ + { + "include": "#markup" + } + ] + }, + { + "name": "comment.line.double-slash.typst", + "begin": "//", + "end": "\n", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.typst" + } + } + }, + { + "name": "punctuation.separator.colon.typst", + "match": ":" + }, + { + "name": "punctuation.separator.comma.typst", + "match": "," + }, + { + "name": "keyword.operator.typst", + "match": "=>|\\.\\." + }, + { + "name": "keyword.operator.relational.typst", + "match": "==|!=|<=|<|>=|>" + }, + { + "name": "keyword.operator.assignment.typst", + "match": "\\+=|-=|\\*=|/=|=" + }, + { + "name": "keyword.operator.arithmetic.typst", + "match": "\\+|\\|/|(?