diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3cef378af6ce..a1c23898820c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -141,6 +141,12 @@ repos: # This also renames files, invalidating the list of files provided to # subsequent checks so we fail-fast if this makes changes. fail_fast: true + - id: build-textmate-grammar + name: Build TextMate grammar + entry: scripts/update_tm_language.py + language: system + files: ^utils/vscode/carbon\.tmLanguage\.json$ + pass_filenames: false - id: check-toolchain-diagnostics name: Check toolchain diagnostics entry: toolchain/diagnostics/check_diagnostics.py @@ -202,7 +208,7 @@ repos: - '' - '*/' - --custom_format - - '\.(plist)$' + - '\.(plist|tmLanguage)$' - '' diff --git a/scripts/update_tm_language.py b/scripts/update_tm_language.py new file mode 100755 index 000000000000..e28ff1ac293a --- /dev/null +++ b/scripts/update_tm_language.py @@ -0,0 +1,62 @@ +#!/usr/bin/env -S uv run --script + +# /// script +# requires-python = ">=3.12" +# /// + +"""Updates the TextMate plist grammar from the VS Code JSON grammar.""" + +__copyright__ = """ +Part of the Carbon Language project, under the Apache License v2.0 with LLVM +Exceptions. See /LICENSE for license information. +SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +""" + +import json +import plistlib +from pathlib import Path + + +def main() -> None: + # Find repository root. + repo_root = Path(__file__).resolve().parents[1] + + json_path = repo_root / "utils" / "vscode" / "carbon.tmLanguage.json" + plist_path = ( + repo_root / "utils" / "textmate" / "Syntaxes" / "carbon.tmLanguage" + ) + + # Read and parse the JSON grammar. + with open(json_path, "r", encoding="utf-8") as f: + grammar_data = json.load(f) + + # Generate plist bytes. + plist_bytes = plistlib.dumps(grammar_data, fmt=plistlib.FMT_XML) + + # Replace the file header. + file_header = b""" + + + + + + +""" + (_, body) = plist_bytes.split(b" + + + + + + + + + $schema + https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json + fileTypes + + carbon + + foldingStartMarker + \{\s*$ + foldingStopMarker + ^\s*\} + name + carbon + patterns + + + include + #comments + + + include + #cpp-inline + + + include + #strings + + + include + #types + + + include + #functions + + + include + #variables + + + include + #operators + + + include + #special-keywords + + + include + #introducer-keywords + + + include + #modifier-keywords + + + include + #misc-keywords + + + include + #self-keywords + + + include + #underscore + + + include + #true-false + + + include + #type-literals + + + include + #numbers + + + include + #parameter-bindings + + + include + #customs + + + repository + + comments + + patterns + + + match + ^\s*(?=//\s).*$ + name + comment.line.carbon + + + match + ^\s*//@dump-sem-ir-(begin|end)\s*$ + name + comment.line.carbon + + + match + ^\s*//@include-in-dumps\s*$ + name + comment.line.carbon + + + + common + + comments + + For including comments, operators, keywords, literals, and language constants + in other rules that use begin/end. This way we do not accidentally override their + highlighting in complex rules. + + patterns + + + include + #comments + + + include + #strings + + + include + #operators + + + include + #special-keywords + + + include + #introducer-keywords + + + include + #modifier-keywords + + + include + #misc-keywords + + + include + #self-keywords + + + include + #true-false + + + include + #type-literals + + + include + #numbers + + + + cpp-inline + + patterns + + + begin + \b(import)\b\s+\b(Cpp)\b\s+\b(inline)\b\s*(''')([^\s'#]*\n)? + beginCaptures + + 1 + + name + storage.type.carbon + + 2 + + name + support.type.property-name.carbon + + 3 + + name + storage.type.carbon + + 4 + + name + string.quoted.triple.carbon + + 5 + + name + constant.character.escape.carbon + + + comment + C++ inline import (triple-quoted) + contentName + meta.embedded.block.cpp + end + (''')\s*(;) + endCaptures + + 1 + + name + string.quoted.triple.carbon + + 2 + + name + punctuation.terminator.carbon + + + patterns + + + include + source.cpp + + + + + begin + \b(import)\b\s+\b(Cpp)\b\s+\b(inline)\b\s*(") + beginCaptures + + 1 + + name + storage.type.carbon + + 2 + + name + support.type.property-name.carbon + + 3 + + name + storage.type.carbon + + 4 + + name + string.quoted.double.carbon + + + comment + C++ inline import (double-quoted) + contentName + meta.embedded.inline.cpp + end + (")\s*(;) + endCaptures + + 1 + + name + string.quoted.double.carbon + + 2 + + name + punctuation.terminator.carbon + + + patterns + + + include + source.cpp + + + + + begin + \b(inline)\b\s+\b(Cpp)\b\s*(''')([^\s'#]*\n)? + beginCaptures + + 1 + + name + storage.type.carbon + + 2 + + name + support.type.property-name.carbon + + 3 + + name + string.quoted.triple.carbon + + 4 + + name + constant.character.escape.carbon + + + comment + C++ inline block (triple-quoted) + contentName + meta.embedded.block.cpp + end + (''')\s*(;) + endCaptures + + 1 + + name + string.quoted.triple.carbon + + 2 + + name + punctuation.terminator.carbon + + + patterns + + + include + source.cpp + + + + + begin + \b(inline)\b\s+\b(Cpp)\b\s*(") + beginCaptures + + 1 + + name + storage.type.carbon + + 2 + + name + support.type.property-name.carbon + + 3 + + name + string.quoted.double.carbon + + + comment + C++ inline block (double-quoted) + contentName + meta.embedded.inline.cpp + end + (")\s*(;) + endCaptures + + 1 + + name + string.quoted.double.carbon + + 2 + + name + punctuation.terminator.carbon + + + patterns + + + include + source.cpp + + + + + + customs + + comment + For rules that should be checked last. + patterns + + + match + (?<=\bpackage\s)\w+ + name + support.class.carbon + + + match + (?<=\bCore\s)\w+ + name + support.class.carbon + + + match + (?<=\bimport\s)\w+ + name + support.type.property-name.carbon + + + comment + Matches function calls. + match + \b\w+\s*\( + name + support.function.carbon + + + comment + Matches unidentified words as variables. + match + \b\w+\b + name + support.variable.carbon + + + + functions + + name + meta.function.carbon + patterns + + + begin + \bfn\b + beginCaptures + + 0 + + name + storage.type.carbon + + + comment + Matches function declarations. + end + (?=[\[\(]) + patterns + + + include + #common + + + match + \w+ + name + support.function.carbon + + + + + + introducer-keywords + + patterns + + + match + \b(adapt|alias|choice|class|constraint|fn|import|inline|interface|let|library|namespace|var)\b + name + storage.type.carbon + + + match + \b(base)\b(?!\s*class\b) + name + storage.type.carbon + + + match + \b(export)\b(?!\s*import\b) + name + storage.type.carbon + + + match + \b(impl)\b(?!\s*(fn|library|package)\b) + name + storage.type.carbon + + + match + \b(package)\b(?!\.) + name + storage.type.carbon + + + + misc-keywords + + patterns + + + match + \b(auto|destructor|forall|friend|observe|override|require)\b + name + keyword.other.carbon + + + match + (?<=\.)\b(base)\b + name + keyword.other.carbon + + + + modifier-keywords + + patterns + + + match + \b(abstract|const|extend|extern|final|private|protected|static|virtual)\b + name + storage.modifier.carbon + + + match + \b(base)\b(?=\s*class\b) + name + storage.modifier.carbon + + + match + \b(default)\b(?!\s*=>) + name + storage.modifier.carbon + + + match + \b(export)\b(?=\s*import\b) + name + storage.modifier.carbon + + + match + \b(impl)\b(?=\s*(fn|library|package)\b) + name + storage.modifier.carbon + + + + numbers + + comment + Invalid formats are also highlighted. Language server handles error highlighting + patterns + + + match + 0x[_0-9a-fA-F]*(\.[_0-9a-fA-F]+(p[-+]?[0-9]+)?)? + name + constant.numeric.carbon + + + match + 0b[_01]* + name + constant.numeric.carbon + + + match + [0-9][_0-9]*(\.[_0-9]+(e[-+]?[0-9]+)?)? + name + constant.numeric.carbon + + + + operators + + patterns + + + match + \b(>>=|<=>|<<=|\&=|==|!=|>=|>>|<=|<<|-=|->|--|%=|\|=|\+=|\+\+|/=|\*=|\&|\^|=|>|<|-|%|\.|\||\+|/|\*)\b + name + keyword.operator.carbon + + + match + \b(and|as|impls|in|like|not|or|partial|ref|template|where)\b + name + keyword.control.carbon + + + + parameter-bindings + + patterns + + + captures + + 1 + + name + support.variable.carbon + + + comment + Matches parameter bindings. + match + \b(\w+)\s*(?=:) + + + + self-keywords + + patterns + + + match + \b(self|Self)\b + name + variable.language.carbon + + + + special-keywords + + patterns + + + match + \b(break|case|continue|else|if|for|match|return|returned|then|while)\b + name + keyword.control.carbon + + + match + \b(default)\b(?=\s*=>) + name + keyword.control.carbon + + + + string_escapes + + patterns + + + match + \\([tnr'"0\0]|x[0-9A-F]{2}|u\{[0-9A-F]{4,}\}) + name + constant.character.escape.carbon + + + + strings + + patterns + + + begin + '''([^\s'#]*\n)? + beginCaptures + + 1 + + name + constant.character.escape.carbon + + + end + ''' + name + string.quoted.triple.carbon + patterns + + + include + #string_escapes + + + + + begin + " + end + " + name + string.quoted.double.carbon + patterns + + + include + #string_escapes + + + + + + true-false + + patterns + + + match + \b(true|false)\b + name + constant.language.carbon + + + + type-literals + + patterns + + + match + \b(array|bool|char|str|type)\b + name + constant.language.carbon + + + comment + Match common numeric type literals. Language server should highlight other valid literals. + match + \b[iuf](8|16|32|64|128)\b + name + constant.language.carbon + + + + types + + name + meta.type.carbon + patterns + + + begin + \b((adapt|alias|class|constraint|interface|impl)|(as|impls))\b + beginCaptures + + 2 + + name + storage.type.carbon + + 3 + + name + keyword.control.carbon + + + comment + Matches type, constraint, and implementation declarations, and explicit casts. + end + (?=[;{]) + patterns + + + include + #common + + + include + #parameter-bindings + + + match + \w+ + name + support.type.carbon + + + + + begin + :!? + comment + Matches types in bindings. + end + (?=([;{=]|->|in|where)) + patterns + + + include + #common + + + include + #variables + + + include + #parameter-bindings + + + match + \w+ + name + support.type.carbon + + + + + begin + -> + comment + Matches function return types. + end + (?=([;{]|=>)) + patterns + + + include + #common + + + match + \w+ + name + support.type.carbon + + + + + begin + \bwhere\b + beginCaptures + + 0 + + name + keyword.control.carbon + + + comment + Matches types in where clause. + end + (?=[;{]) + patterns + + + include + #common + + + include + #variables + + + include + #parameter-bindings + + + match + \w+ + name + support.type.carbon + + + + + begin + \bchoice\b + beginCaptures + + 0 + + name + storage.type.carbon + + + comment + Matches choices. + end + (?=[;}]) + patterns + + + include + #common + + + include + #variables + + + include + #parameter-bindings + + + match + \w+ + name + support.type.carbon + + + begin + \{ + comment + Matches the choice values. + end + (?=}) + patterns + + + include + #common + + + match + \w+ + name + variable.other.enummember.carbon + + + + + + + + underscore + + patterns + + + match + \b(_)\b + name + variable.language.carbon + + + + variables + + name + meta.variable.carbon + patterns + + + begin + \b(var|let)\b + beginCaptures + + 0 + + name + storage.type.carbon + + + comment + Matches variable declarations. + end + (?=:) + patterns + + + include + #common + + + match + \w+ + name + support.variable.carbon + + + + + + + scopeName + source.carbon + uuid + 4568a54d-9a79-41ac-a36b-05916252763b + + diff --git a/utils/textmate/Syntaxes/carbon.tmLanguage.json b/utils/textmate/Syntaxes/carbon.tmLanguage.json deleted file mode 100644 index ee7475bfd911..000000000000 --- a/utils/textmate/Syntaxes/carbon.tmLanguage.json +++ /dev/null @@ -1,537 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "carbon", - "scopeName": "source.carbon", - "foldingStartMarker": "\\{\\s*$", - "foldingStopMarker": "^\\s*\\}", - "fileTypes": ["carbon"], - "patterns": [ - { - "include": "#comments" - }, - { - "include": "#cpp-inline" - }, - { - "include": "#strings" - }, - { - "include": "#types" - }, - { - "include": "#functions" - }, - { - "include": "#variables" - }, - { - "include": "#operators" - }, - { - "include": "#special-keywords" - }, - { - "include": "#introducer-keywords" - }, - { - "include": "#modifier-keywords" - }, - { - "include": "#misc-keywords" - }, - { - "include": "#self-keywords" - }, - { - "include": "#underscore" - }, - { - "include": "#true-false" - }, - { - "include": "#type-literals" - }, - { - "include": "#numbers" - }, - { - "include": "#parameter-bindings" - }, - { - "include": "#customs" - } - ], - "repository": { - "cpp-inline": { - "patterns": [ - { - "comment": "C++ inline import (triple-quoted)", - "begin": "\\b(import)\\b\\s+\\b(Cpp)\\b\\s+\\b(inline)\\b\\s*(''')([^\\s'#]*\\n)?", - "beginCaptures": { - "1": { "name": "storage.type.carbon" }, - "2": { "name": "support.type.property-name.carbon" }, - "3": { "name": "storage.type.carbon" }, - "4": { "name": "string.quoted.triple.carbon" }, - "5": { "name": "constant.character.escape.carbon" } - }, - "end": "(''')\\s*(;)", - "endCaptures": { - "1": { "name": "string.quoted.triple.carbon" }, - "2": { "name": "punctuation.terminator.carbon" } - }, - "contentName": "meta.embedded.block.cpp", - "patterns": [ - { - "include": "source.cpp" - } - ] - }, - { - "comment": "C++ inline import (double-quoted)", - "begin": "\\b(import)\\b\\s+\\b(Cpp)\\b\\s+\\b(inline)\\b\\s*(\")", - "beginCaptures": { - "1": { "name": "storage.type.carbon" }, - "2": { "name": "support.type.property-name.carbon" }, - "3": { "name": "storage.type.carbon" }, - "4": { "name": "string.quoted.double.carbon" } - }, - "end": "(\")\\s*(;)", - "endCaptures": { - "1": { "name": "string.quoted.double.carbon" }, - "2": { "name": "punctuation.terminator.carbon" } - }, - "contentName": "meta.embedded.inline.cpp", - "patterns": [ - { - "include": "source.cpp" - } - ] - }, - { - "comment": "C++ inline block (triple-quoted)", - "begin": "\\b(inline)\\b\\s+\\b(Cpp)\\b\\s*(''')([^\\s'#]*\\n)?", - "beginCaptures": { - "1": { "name": "storage.type.carbon" }, - "2": { "name": "support.type.property-name.carbon" }, - "3": { "name": "string.quoted.triple.carbon" }, - "4": { "name": "constant.character.escape.carbon" } - }, - "end": "(''')\\s*(;)", - "endCaptures": { - "1": { "name": "string.quoted.triple.carbon" }, - "2": { "name": "punctuation.terminator.carbon" } - }, - "contentName": "meta.embedded.block.cpp", - "patterns": [ - { - "include": "source.cpp" - } - ] - }, - { - "comment": "C++ inline block (double-quoted)", - "begin": "\\b(inline)\\b\\s+\\b(Cpp)\\b\\s*(\")", - "beginCaptures": { - "1": { "name": "storage.type.carbon" }, - "2": { "name": "support.type.property-name.carbon" }, - "3": { "name": "string.quoted.double.carbon" } - }, - "end": "(\")\\s*(;)", - "endCaptures": { - "1": { "name": "string.quoted.double.carbon" }, - "2": { "name": "punctuation.terminator.carbon" } - }, - "contentName": "meta.embedded.inline.cpp", - "patterns": [ - { - "include": "source.cpp" - } - ] - } - ] - }, - "comments": { - "patterns": [ - { - "name": "comment.line.carbon", - "match": "^\\s*(?=//\\s).*$" - }, - { - "name": "comment.line.carbon", - "match": "^\\s*//@dump-sem-ir-(begin|end)\\s*$" - }, - { - "name": "comment.line.carbon", - "match": "^\\s*//@include-in-dumps\\s*$" - } - ] - }, - "string_escapes": { - "patterns": [ - { - "name": "constant.character.escape.carbon", - "match": "\\\\([tnr'\"0\\0]|x[0-9A-F]{2}|u\\{[0-9A-F]{4,}\\})" - } - ] - }, - "strings": { - "patterns": [ - { - "name": "string.quoted.triple.carbon", - "begin": "'''([^\\s'#]*\\n)?", - "end": "'''", - "beginCaptures": { - "1": { - "name": "constant.character.escape.carbon" - } - }, - "patterns": [ - { - "include": "#string_escapes" - } - ] - }, - { - "name": "string.quoted.double.carbon", - "begin": "\"", - "end": "\"", - "patterns": [ - { - "include": "#string_escapes" - } - ] - } - ] - }, - "types": { - "name": "meta.type.carbon", - "patterns": [ - { - "comment": "Matches type, constraint, and implementation declarations, and explicit casts.", - "begin": "\\b((adapt|alias|class|constraint|interface|impl)|(as|impls))\\b", - "beginCaptures": { - "2": { "name": "storage.type.carbon" }, - "3": { "name": "keyword.control.carbon" } - }, - "end": "(?=[;{])", - "patterns": [ - { "include": "#common" }, - { "include": "#parameter-bindings" }, - { - "name": "support.type.carbon", - "match": "\\w+" - } - ] - }, - { - "comment": "Matches types in bindings.", - "begin": ":!?", - "end": "(?=([;{=]|->|in|where))", - "patterns": [ - { "include": "#common" }, - { "include": "#variables" }, - { "include": "#parameter-bindings" }, - { - "name": "support.type.carbon", - "match": "\\w+" - } - ] - }, - { - "comment": "Matches function return types.", - "begin": "->", - "end": "(?=([;{]|=>))", - "patterns": [ - { "include": "#common" }, - { - "name": "support.type.carbon", - "match": "\\w+" - } - ] - }, - { - "comment": "Matches types in where clause.", - "begin": "\\bwhere\\b", - "beginCaptures": { - "0": { "name": "keyword.control.carbon" } - }, - "end": "(?=[;{])", - "patterns": [ - { "include": "#common" }, - { "include": "#variables" }, - { "include": "#parameter-bindings" }, - { - "name": "support.type.carbon", - "match": "\\w+" - } - ] - }, - { - "comment": "Matches choices.", - "begin": "\\bchoice\\b", - "beginCaptures": { - "0": { "name": "storage.type.carbon" } - }, - "end": "(?=[;}])", - "patterns": [ - { "include": "#common" }, - { "include": "#variables" }, - { "include": "#parameter-bindings" }, - { - "name": "support.type.carbon", - "match": "\\w+" - }, - { - "comment": "Matches the choice values.", - "begin": "\\{", - "end": "(?=})", - "patterns": [ - { "include": "#common" }, - { - "name": "variable.other.enummember.carbon", - "match": "\\w+" - } - ] - } - ] - } - ] - }, - "functions": { - "name": "meta.function.carbon", - "patterns": [ - { - "comment": "Matches function declarations.", - "begin": "\\bfn\\b", - "beginCaptures": { - "0": { "name": "storage.type.carbon" } - }, - "end": "(?=[\\[\\(])", - "patterns": [ - { "include": "#common" }, - { - "name": "support.function.carbon", - "match": "\\w+" - } - ] - } - ] - }, - "variables": { - "name": "meta.variable.carbon", - "patterns": [ - { - "comment": "Matches variable declarations.", - "begin": "\\b(var|let)\\b", - "beginCaptures": { - "0": { "name": "storage.type.carbon" } - }, - "end": "(?=:)", - "patterns": [ - { "include": "#common" }, - { - "name": "support.variable.carbon", - "match": "\\w+" - } - ] - } - ] - }, - "operators": { - "patterns": [ - { - "name": "keyword.operator.carbon", - "match": "\\b(>>=|<=>|<<=|\\&=|==|!=|>=|>>|<=|<<|-=|->|--|%=|\\|=|\\+=|\\+\\+|/=|\\*=|\\&|\\^|=|>|<|-|%|\\.|\\||\\+|/|\\*)\\b" - }, - { - "name": "keyword.control.carbon", - "match": "\\b(and|as|impls|in|like|not|or|partial|ref|template|where)\\b" - } - ] - }, - "special-keywords": { - "patterns": [ - { - "name": "keyword.control.carbon", - "match": "\\b(break|case|continue|else|if|for|match|return|returned|then|while)\\b" - }, - { - "name": "keyword.control.carbon", - "match": "\\b(default)\\b(?=\\s*=>)" - } - ] - }, - "introducer-keywords": { - "patterns": [ - { - "name": "storage.type.carbon", - "match": "\\b(adapt|alias|choice|class|constraint|fn|import|inline|interface|let|library|namespace|var)\\b" - }, - { - "name": "storage.type.carbon", - "match": "\\b(base)\\b(?!\\s*class\\b)" - }, - { - "name": "storage.type.carbon", - "match": "\\b(export)\\b(?!\\s*import\\b)" - }, - { - "name": "storage.type.carbon", - "match": "\\b(impl)\\b(?!\\s*(fn|library|package)\\b)" - }, - { - "name": "storage.type.carbon", - "match": "\\b(package)\\b(?!\\.)" - } - ] - }, - "modifier-keywords": { - "patterns": [ - { - "name": "storage.modifier.carbon", - "match": "\\b(abstract|const|extend|extern|final|private|protected|static|virtual)\\b" - }, - { - "name": "storage.modifier.carbon", - "match": "\\b(base)\\b(?=\\s*class\\b)" - }, - { - "name": "storage.modifier.carbon", - "match": "\\b(default)\\b(?!\\s*=>)" - }, - { - "name": "storage.modifier.carbon", - "match": "\\b(export)\\b(?=\\s*import\\b)" - }, - { - "name": "storage.modifier.carbon", - "match": "\\b(impl)\\b(?=\\s*(fn|library|package)\\b)" - } - ] - }, - "misc-keywords": { - "patterns": [ - { - "name": "keyword.other.carbon", - "match": "\\b(auto|destructor|forall|friend|observe|override|require)\\b" - }, - { - "name": "keyword.other.carbon", - "match": "(?<=\\.)\\b(base)\\b" - } - ] - }, - "self-keywords": { - "patterns": [ - { - "name": "variable.language.carbon", - "match": "\\b(self|Self)\\b" - } - ] - }, - "underscore": { - "patterns": [ - { - "name": "variable.language.carbon", - "match": "\\b(_)\\b" - } - ] - }, - "true-false": { - "patterns": [ - { - "name": "constant.language.carbon", - "match": "\\b(true|false)\\b" - } - ] - }, - "type-literals": { - "patterns": [ - { - "name": "constant.language.carbon", - "match": "\\b(array|bool|char|str|type)\\b" - }, - { - "name": "constant.language.carbon", - "comment": "Match common numeric type literals. Language server should highlight other valid literals.", - "match": "\\b[iuf](8|16|32|64|128)\\b" - } - ] - }, - "numbers": { - "comment": "Invalid formats are also highlighted. Language server handles error highlighting", - "patterns": [ - { - "name": "constant.numeric.carbon", - "match": "0x[_0-9a-fA-F]*(\\.[_0-9a-fA-F]+(p[-+]?[0-9]+)?)?" - }, - { - "name": "constant.numeric.carbon", - "match": "0b[_01]*" - }, - { - "name": "constant.numeric.carbon", - "match": "[0-9][_0-9]*(\\.[_0-9]+(e[-+]?[0-9]+)?)?" - } - ] - }, - "parameter-bindings": { - "patterns": [ - { - "comment": "Matches parameter bindings.", - "match": "\\b(\\w+)\\s*(?=:)", - "captures": { - "1": { "name": "support.variable.carbon" } - } - } - ] - }, - "customs": { - "comment": "For rules that should be checked last.", - "patterns": [ - { - "name": "support.class.carbon", - "match": "(?<=\\bpackage\\s)\\w+" - }, - { - "name": "support.class.carbon", - "match": "(?<=\\bCore\\s)\\w+" - }, - { - "name": "support.type.property-name.carbon", - "match": "(?<=\\bimport\\s)\\w+" - }, - { - "comment": "Matches function calls.", - "name": "support.function.carbon", - "match": "\\b\\w+\\s*\\(" - }, - { - "comment": "Matches unidentified words as variables.", - "name": "support.variable.carbon", - "match": "\\b\\w+\\b" - } - ] - }, - "common": { - "comments": [ - "For including comments, operators, keywords, literals, and language constants ", - "in other rules that use begin/end. This way we do not accidentally override their ", - "highlighting in complex rules." - ], - "patterns": [ - { "include": "#comments" }, - { "include": "#strings" }, - { "include": "#operators" }, - { "include": "#special-keywords" }, - { "include": "#introducer-keywords" }, - { "include": "#modifier-keywords" }, - { "include": "#misc-keywords" }, - { "include": "#self-keywords" }, - { "include": "#true-false" }, - { "include": "#type-literals" }, - { "include": "#numbers" } - ] - } - } -} diff --git a/utils/textmate/info.plist b/utils/textmate/info.plist index 0c9dbede8a8b..c379fecbae65 100644 --- a/utils/textmate/info.plist +++ b/utils/textmate/info.plist @@ -8,6 +8,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + contactName Carbon Developers @@ -15,7 +16,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception Support for Carbon Language name - carbon + Carbon ordering @@ -24,4 +25,5 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception uuid 6152A817-84AE-47A8-96DB-0B50DF2EEC10 + diff --git a/utils/vscode/carbon.tmLanguage.json b/utils/vscode/carbon.tmLanguage.json deleted file mode 120000 index d5c68e61e9e7..000000000000 --- a/utils/vscode/carbon.tmLanguage.json +++ /dev/null @@ -1 +0,0 @@ -../textmate/Syntaxes/carbon.tmLanguage.json \ No newline at end of file diff --git a/utils/vscode/carbon.tmLanguage.json b/utils/vscode/carbon.tmLanguage.json new file mode 100644 index 000000000000..87cfaa80f47e --- /dev/null +++ b/utils/vscode/carbon.tmLanguage.json @@ -0,0 +1,538 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "uuid": "4568a54d-9a79-41ac-a36b-05916252763b", + "name": "carbon", + "scopeName": "source.carbon", + "foldingStartMarker": "\\{\\s*$", + "foldingStopMarker": "^\\s*\\}", + "fileTypes": ["carbon"], + "patterns": [ + { + "include": "#comments" + }, + { + "include": "#cpp-inline" + }, + { + "include": "#strings" + }, + { + "include": "#types" + }, + { + "include": "#functions" + }, + { + "include": "#variables" + }, + { + "include": "#operators" + }, + { + "include": "#special-keywords" + }, + { + "include": "#introducer-keywords" + }, + { + "include": "#modifier-keywords" + }, + { + "include": "#misc-keywords" + }, + { + "include": "#self-keywords" + }, + { + "include": "#underscore" + }, + { + "include": "#true-false" + }, + { + "include": "#type-literals" + }, + { + "include": "#numbers" + }, + { + "include": "#parameter-bindings" + }, + { + "include": "#customs" + } + ], + "repository": { + "cpp-inline": { + "patterns": [ + { + "comment": "C++ inline import (triple-quoted)", + "begin": "\\b(import)\\b\\s+\\b(Cpp)\\b\\s+\\b(inline)\\b\\s*(''')([^\\s'#]*\\n)?", + "beginCaptures": { + "1": { "name": "storage.type.carbon" }, + "2": { "name": "support.type.property-name.carbon" }, + "3": { "name": "storage.type.carbon" }, + "4": { "name": "string.quoted.triple.carbon" }, + "5": { "name": "constant.character.escape.carbon" } + }, + "end": "(''')\\s*(;)", + "endCaptures": { + "1": { "name": "string.quoted.triple.carbon" }, + "2": { "name": "punctuation.terminator.carbon" } + }, + "contentName": "meta.embedded.block.cpp", + "patterns": [ + { + "include": "source.cpp" + } + ] + }, + { + "comment": "C++ inline import (double-quoted)", + "begin": "\\b(import)\\b\\s+\\b(Cpp)\\b\\s+\\b(inline)\\b\\s*(\")", + "beginCaptures": { + "1": { "name": "storage.type.carbon" }, + "2": { "name": "support.type.property-name.carbon" }, + "3": { "name": "storage.type.carbon" }, + "4": { "name": "string.quoted.double.carbon" } + }, + "end": "(\")\\s*(;)", + "endCaptures": { + "1": { "name": "string.quoted.double.carbon" }, + "2": { "name": "punctuation.terminator.carbon" } + }, + "contentName": "meta.embedded.inline.cpp", + "patterns": [ + { + "include": "source.cpp" + } + ] + }, + { + "comment": "C++ inline block (triple-quoted)", + "begin": "\\b(inline)\\b\\s+\\b(Cpp)\\b\\s*(''')([^\\s'#]*\\n)?", + "beginCaptures": { + "1": { "name": "storage.type.carbon" }, + "2": { "name": "support.type.property-name.carbon" }, + "3": { "name": "string.quoted.triple.carbon" }, + "4": { "name": "constant.character.escape.carbon" } + }, + "end": "(''')\\s*(;)", + "endCaptures": { + "1": { "name": "string.quoted.triple.carbon" }, + "2": { "name": "punctuation.terminator.carbon" } + }, + "contentName": "meta.embedded.block.cpp", + "patterns": [ + { + "include": "source.cpp" + } + ] + }, + { + "comment": "C++ inline block (double-quoted)", + "begin": "\\b(inline)\\b\\s+\\b(Cpp)\\b\\s*(\")", + "beginCaptures": { + "1": { "name": "storage.type.carbon" }, + "2": { "name": "support.type.property-name.carbon" }, + "3": { "name": "string.quoted.double.carbon" } + }, + "end": "(\")\\s*(;)", + "endCaptures": { + "1": { "name": "string.quoted.double.carbon" }, + "2": { "name": "punctuation.terminator.carbon" } + }, + "contentName": "meta.embedded.inline.cpp", + "patterns": [ + { + "include": "source.cpp" + } + ] + } + ] + }, + "comments": { + "patterns": [ + { + "name": "comment.line.carbon", + "match": "^\\s*(?=//\\s).*$" + }, + { + "name": "comment.line.carbon", + "match": "^\\s*//@dump-sem-ir-(begin|end)\\s*$" + }, + { + "name": "comment.line.carbon", + "match": "^\\s*//@include-in-dumps\\s*$" + } + ] + }, + "string_escapes": { + "patterns": [ + { + "name": "constant.character.escape.carbon", + "match": "\\\\([tnr'\"0\\0]|x[0-9A-F]{2}|u\\{[0-9A-F]{4,}\\})" + } + ] + }, + "strings": { + "patterns": [ + { + "name": "string.quoted.triple.carbon", + "begin": "'''([^\\s'#]*\\n)?", + "end": "'''", + "beginCaptures": { + "1": { + "name": "constant.character.escape.carbon" + } + }, + "patterns": [ + { + "include": "#string_escapes" + } + ] + }, + { + "name": "string.quoted.double.carbon", + "begin": "\"", + "end": "\"", + "patterns": [ + { + "include": "#string_escapes" + } + ] + } + ] + }, + "types": { + "name": "meta.type.carbon", + "patterns": [ + { + "comment": "Matches type, constraint, and implementation declarations, and explicit casts.", + "begin": "\\b((adapt|alias|class|constraint|interface|impl)|(as|impls))\\b", + "beginCaptures": { + "2": { "name": "storage.type.carbon" }, + "3": { "name": "keyword.control.carbon" } + }, + "end": "(?=[;{])", + "patterns": [ + { "include": "#common" }, + { "include": "#parameter-bindings" }, + { + "name": "support.type.carbon", + "match": "\\w+" + } + ] + }, + { + "comment": "Matches types in bindings.", + "begin": ":!?", + "end": "(?=([;{=]|->|in|where))", + "patterns": [ + { "include": "#common" }, + { "include": "#variables" }, + { "include": "#parameter-bindings" }, + { + "name": "support.type.carbon", + "match": "\\w+" + } + ] + }, + { + "comment": "Matches function return types.", + "begin": "->", + "end": "(?=([;{]|=>))", + "patterns": [ + { "include": "#common" }, + { + "name": "support.type.carbon", + "match": "\\w+" + } + ] + }, + { + "comment": "Matches types in where clause.", + "begin": "\\bwhere\\b", + "beginCaptures": { + "0": { "name": "keyword.control.carbon" } + }, + "end": "(?=[;{])", + "patterns": [ + { "include": "#common" }, + { "include": "#variables" }, + { "include": "#parameter-bindings" }, + { + "name": "support.type.carbon", + "match": "\\w+" + } + ] + }, + { + "comment": "Matches choices.", + "begin": "\\bchoice\\b", + "beginCaptures": { + "0": { "name": "storage.type.carbon" } + }, + "end": "(?=[;}])", + "patterns": [ + { "include": "#common" }, + { "include": "#variables" }, + { "include": "#parameter-bindings" }, + { + "name": "support.type.carbon", + "match": "\\w+" + }, + { + "comment": "Matches the choice values.", + "begin": "\\{", + "end": "(?=})", + "patterns": [ + { "include": "#common" }, + { + "name": "variable.other.enummember.carbon", + "match": "\\w+" + } + ] + } + ] + } + ] + }, + "functions": { + "name": "meta.function.carbon", + "patterns": [ + { + "comment": "Matches function declarations.", + "begin": "\\bfn\\b", + "beginCaptures": { + "0": { "name": "storage.type.carbon" } + }, + "end": "(?=[\\[\\(])", + "patterns": [ + { "include": "#common" }, + { + "name": "support.function.carbon", + "match": "\\w+" + } + ] + } + ] + }, + "variables": { + "name": "meta.variable.carbon", + "patterns": [ + { + "comment": "Matches variable declarations.", + "begin": "\\b(var|let)\\b", + "beginCaptures": { + "0": { "name": "storage.type.carbon" } + }, + "end": "(?=:)", + "patterns": [ + { "include": "#common" }, + { + "name": "support.variable.carbon", + "match": "\\w+" + } + ] + } + ] + }, + "operators": { + "patterns": [ + { + "name": "keyword.operator.carbon", + "match": "\\b(>>=|<=>|<<=|\\&=|==|!=|>=|>>|<=|<<|-=|->|--|%=|\\|=|\\+=|\\+\\+|/=|\\*=|\\&|\\^|=|>|<|-|%|\\.|\\||\\+|/|\\*)\\b" + }, + { + "name": "keyword.control.carbon", + "match": "\\b(and|as|impls|in|like|not|or|partial|ref|template|where)\\b" + } + ] + }, + "special-keywords": { + "patterns": [ + { + "name": "keyword.control.carbon", + "match": "\\b(break|case|continue|else|if|for|match|return|returned|then|while)\\b" + }, + { + "name": "keyword.control.carbon", + "match": "\\b(default)\\b(?=\\s*=>)" + } + ] + }, + "introducer-keywords": { + "patterns": [ + { + "name": "storage.type.carbon", + "match": "\\b(adapt|alias|choice|class|constraint|fn|import|inline|interface|let|library|namespace|var)\\b" + }, + { + "name": "storage.type.carbon", + "match": "\\b(base)\\b(?!\\s*class\\b)" + }, + { + "name": "storage.type.carbon", + "match": "\\b(export)\\b(?!\\s*import\\b)" + }, + { + "name": "storage.type.carbon", + "match": "\\b(impl)\\b(?!\\s*(fn|library|package)\\b)" + }, + { + "name": "storage.type.carbon", + "match": "\\b(package)\\b(?!\\.)" + } + ] + }, + "modifier-keywords": { + "patterns": [ + { + "name": "storage.modifier.carbon", + "match": "\\b(abstract|const|extend|extern|final|private|protected|static|virtual)\\b" + }, + { + "name": "storage.modifier.carbon", + "match": "\\b(base)\\b(?=\\s*class\\b)" + }, + { + "name": "storage.modifier.carbon", + "match": "\\b(default)\\b(?!\\s*=>)" + }, + { + "name": "storage.modifier.carbon", + "match": "\\b(export)\\b(?=\\s*import\\b)" + }, + { + "name": "storage.modifier.carbon", + "match": "\\b(impl)\\b(?=\\s*(fn|library|package)\\b)" + } + ] + }, + "misc-keywords": { + "patterns": [ + { + "name": "keyword.other.carbon", + "match": "\\b(auto|destructor|forall|friend|observe|override|require)\\b" + }, + { + "name": "keyword.other.carbon", + "match": "(?<=\\.)\\b(base)\\b" + } + ] + }, + "self-keywords": { + "patterns": [ + { + "name": "variable.language.carbon", + "match": "\\b(self|Self)\\b" + } + ] + }, + "underscore": { + "patterns": [ + { + "name": "variable.language.carbon", + "match": "\\b(_)\\b" + } + ] + }, + "true-false": { + "patterns": [ + { + "name": "constant.language.carbon", + "match": "\\b(true|false)\\b" + } + ] + }, + "type-literals": { + "patterns": [ + { + "name": "constant.language.carbon", + "match": "\\b(array|bool|char|str|type)\\b" + }, + { + "name": "constant.language.carbon", + "comment": "Match common numeric type literals. Language server should highlight other valid literals.", + "match": "\\b[iuf](8|16|32|64|128)\\b" + } + ] + }, + "numbers": { + "comment": "Invalid formats are also highlighted. Language server handles error highlighting", + "patterns": [ + { + "name": "constant.numeric.carbon", + "match": "0x[_0-9a-fA-F]*(\\.[_0-9a-fA-F]+(p[-+]?[0-9]+)?)?" + }, + { + "name": "constant.numeric.carbon", + "match": "0b[_01]*" + }, + { + "name": "constant.numeric.carbon", + "match": "[0-9][_0-9]*(\\.[_0-9]+(e[-+]?[0-9]+)?)?" + } + ] + }, + "parameter-bindings": { + "patterns": [ + { + "comment": "Matches parameter bindings.", + "match": "\\b(\\w+)\\s*(?=:)", + "captures": { + "1": { "name": "support.variable.carbon" } + } + } + ] + }, + "customs": { + "comment": "For rules that should be checked last.", + "patterns": [ + { + "name": "support.class.carbon", + "match": "(?<=\\bpackage\\s)\\w+" + }, + { + "name": "support.class.carbon", + "match": "(?<=\\bCore\\s)\\w+" + }, + { + "name": "support.type.property-name.carbon", + "match": "(?<=\\bimport\\s)\\w+" + }, + { + "comment": "Matches function calls.", + "name": "support.function.carbon", + "match": "\\b\\w+\\s*\\(" + }, + { + "comment": "Matches unidentified words as variables.", + "name": "support.variable.carbon", + "match": "\\b\\w+\\b" + } + ] + }, + "common": { + "comments": [ + "For including comments, operators, keywords, literals, and language constants ", + "in other rules that use begin/end. This way we do not accidentally override their ", + "highlighting in complex rules." + ], + "patterns": [ + { "include": "#comments" }, + { "include": "#strings" }, + { "include": "#operators" }, + { "include": "#special-keywords" }, + { "include": "#introducer-keywords" }, + { "include": "#modifier-keywords" }, + { "include": "#misc-keywords" }, + { "include": "#self-keywords" }, + { "include": "#true-false" }, + { "include": "#type-literals" }, + { "include": "#numbers" } + ] + } + } +}