diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..91bad27 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Autogenerated synax files +syntax/syntaxes/Scala.tmLanguage.json + +syntax/node_modules diff --git a/syntax/.vscode/launch.json b/syntax/.vscode/launch.json index 8384213..e4ba24d 100644 --- a/syntax/.vscode/launch.json +++ b/syntax/.vscode/launch.json @@ -2,6 +2,17 @@ { "version": "0.1.0", "configurations": [ + { + "type": "extensionHost", + "request": "launch", + "name": "Build && Launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "preLaunchTask": "Generate Scala language file" + }, + { "name": "Launch Extension", "type": "extensionHost", diff --git a/syntax/.vscode/tasks.json b/syntax/.vscode/tasks.json new file mode 100644 index 0000000..1773619 --- /dev/null +++ b/syntax/.vscode/tasks.json @@ -0,0 +1,16 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Generate Scala language file", + "type": "shell", + "command": "npx ts-node src/typescript/GenerateTmLanguageFile.ts > ./syntaxes/Scala.tmLanguage.json", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/syntax/.vscodeignore b/syntax/.vscodeignore new file mode 100644 index 0000000..9dc2806 --- /dev/null +++ b/syntax/.vscodeignore @@ -0,0 +1,7 @@ +.vscode/** +.vscode-test/** +.gitignore +tests/** +src/** +node_modules +.gitkeep \ No newline at end of file diff --git a/syntax/README.md b/syntax/README.md index c60b14a..53a6353 100644 --- a/syntax/README.md +++ b/syntax/README.md @@ -10,9 +10,23 @@ Extension providing Scala syntax. No requirements. +## Development + +The source language file is located at `src/typescript/Scala.tmlanguage.ts`. The output tmLanguage file `syntaxes/Scala.tmLanguage.json` is marked as ignored in git and shouldn't be commited. + +To generate the ouput file either use build command or run: + +```bash +npm install +``` + +The output file is validated against the json schema before being written. + + ## Based on * Plugin: https://github.com/daltonjorge/vscode-scala * Template: https://github.com/sellmerfud/scala.tmbundle (https://github.com/mads-hartmann/scala.tmbundle) +* Textmate json schema: https://github.com/Septh/tmlanguage/blob/master/tmLanguage.schema.json ## License [MIT](LICENSE) diff --git a/syntax/package-lock.json b/syntax/package-lock.json new file mode 100644 index 0000000..434bfac --- /dev/null +++ b/syntax/package-lock.json @@ -0,0 +1,130 @@ +{ + "name": "scala", + "version": "0.2.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "11.13.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.8.tgz", + "integrity": "sha512-szA3x/3miL90ZJxUCzx9haNbK5/zmPieGraZEe4WI+3srN0eGLiT22NXeMHmyhNEopn+IrxqMc7wdVwvPl8meg==", + "dev": true + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "ts-node": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.1.0.tgz", + "integrity": "sha512-34jpuOrxDuf+O6iW1JpgTRDFynUZ1iEqtYruBqh35gICNjN8x+LpVcPAcwzLPi9VU6mdA3ym+x233nZmZp445A==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsc": { + "version": "1.20150623.0", + "resolved": "https://registry.npmjs.org/tsc/-/tsc-1.20150623.0.tgz", + "integrity": "sha1-Trw8d04WkUjLx2inNCUz8ILHpuU=", + "dev": true + }, + "typescript": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", + "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "yn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.0.tgz", + "integrity": "sha512-kKfnnYkbTfrAdd0xICNFw7Atm8nKpLcLv9AZGEt+kczL/WQVai4e2V6ZN8U/O+iI6WrNuJjNNOyu4zfhl9D3Hg==", + "dev": true + } + } +} diff --git a/syntax/package.json b/syntax/package.json index b5f18ca..c454026 100644 --- a/syntax/package.json +++ b/syntax/package.json @@ -15,7 +15,7 @@ }, "icon": "images/smooth-spiral.png", "categories": [ - "Languages" + "Programming Languages" ], "contributes": { "languages": [ @@ -37,8 +37,19 @@ { "language": "scala", "scopeName": "source.scala", - "path": "./syntaxes/Scala.tmLanguage" + "path": "./syntaxes/Scala.tmLanguage.json" } ] + }, + "devDependencies": { + "@types/node": "^11.11.4", + "ajv": "^6.10.0", + "ts-node": "^8.0.2", + "tsc": "^1.20150623.0", + "typescript": "^3.3.3" + }, + "scripts": { + "vscode:prepublish": "test -f ./syntaxes/Scala.tmLanguage.json", + "prepare": "npx ts-node src/typescript/GenerateTmLanguageFile.ts > ./syntaxes/Scala.tmLanguage.json" } } diff --git a/syntax/src/schemas/tmlanguage.json b/syntax/src/schemas/tmlanguage.json new file mode 100644 index 0000000..98c1800 --- /dev/null +++ b/syntax/src/schemas/tmlanguage.json @@ -0,0 +1,267 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "title": "tmLanguage", + "description": "Schema for language grammar description files in Textmate and compatible editors. See https://github.com/Septh/tmlanguage/blob/master/tmLanguage.schema.json", + "type": "object", + "properties": { + "scopeName": { + "description": "This should be a unique name for the grammar, following the convention of being a dot-separated name where each new (left-most) part specializes the name. Normally it would be a two-part name where the first is either `text` or `source` and the second is the name of the language or document type. But if you are specializing an existing type, you probably want to derive the name from the type you are specializing. For example Markdown is `text.html.markdown` and Ruby on Rails (rhtml files) is `text.html.rails`. The advantage of deriving it from (in this case) `text.html` is that everything which works in the `text.html` scope will also work in the `text.html.«something»` scope (but with a lower precedence than something specifically targeting `text.html.«something»`).", + "type": "string", + "pattern": "^[\\w$@][\\w\\-$@]*(?:\\.[\\w$@][\\w\\-$@]*)*$" + }, + "fileTypes": { + "description": "An array of file type extensions that the grammar should (by default) be used with.", + "type": "array", + "items": { + "type": "string" + } + }, + "firstLineMatch": { + "description": "A regular expression which is matched against the first line of the document when it is first loaded. If it matches, the grammar is used for the document.", + "type": "string" + }, + "uuid": { + "description": "When the grammer is part of a larger bundle (ie., grammer + theme + whatever), the uuid helps classify which file is a part of which bundle.", + "type": "string" + }, + "foldingStartMarker": { + "description": "Regular expression that lines (in the document) are matched against. If a line matches the pattern, it starts a foldable block.", + "type": "string" + }, + "foldingStopMarker": { + "description": "Regular expressions that lines (in the document) are matched against. If a line matches pattern, it ends a foldable block.", + "type": "string" + }, + "patterns": { + "description": "An array with the actual rules used to parse the document.", + "$ref": "#/definitions/patterns" + }, + "repository": { + "description": "A dictionary (i.e. key/value pairs) of rules which can be included from other places in the grammar. The key is the name of the rule and the value is the actual rule.", + "$ref": "#/definitions/repository" + }, + "injectionSelector": { + "description": "The key is a scope selector that specifies which scope(s) the current grammar should be injected in.", + "type": "string" + }, + "injections": { + "description": "[VS Code only, it seems] A dictionary (i.e. key/value pairs) of rules which will be injected into an existing grammar. The key is the target scope of the parent grammar and the value is the actual rule to inject.", + "$ref": "#/definitions/repository" + } + }, + "required": [ + "scopeName", + "patterns" + ], + "dependencies": { + "foldingStartMarker": [ + "foldingStopMarker" + ], + "foldingStopMarker": [ + "foldingStartMarker" + ], + "injections": { + "not": { + "required": [ + "injectionSelector" + ] + } + } + }, + "additionalProperties": true, + "definitions": { + "boolean-or-integer": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "number", + "enum": [ + 0, + 1 + ] + } + ] + }, + "patterns": { + "type": "array", + "items": { + "$ref": "#/definitions/rule" + } + }, + "repository": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/rule" + } + }, + "name": { + "type": "string", + "pattern": "^[\\w$@][\\w\\-$@]*(?:(?:\\.| )[\\w$@][\\w\\-$@]*)*$" + }, + "captures": { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "type": "object", + "properties": { + "name": { + "description": "The scope name which gets assigned to the capture matched. This should generally be derived from one of the standard names.", + "type": "string" + }, + "patterns": { + "description": "Yes, captures can be further matched against additional patterns, too.", + "$ref": "#/definitions/patterns" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "rule": { + "type": "object", + "properties": { + "comment": { + "description": "A generic text used to describe or explain the rule.", + "type": "string" + }, + "name": { + "description": "The scope name which gets assigned to the capture matched. This should generally be derived from one of the standard names.", + "type": "string" + }, + "disabled": { + "description": "Marks the rule as disabled. A disabled rule should be ignored by the tokenization engine.", + "$ref": "#/definitions/boolean-or-integer" + }, + "include": { + "description": "This key allows you to reference a different language (value == scope name), recursively reference the grammar itself (value == \"$self\") or a rule declared in this file’s repository (value starts with a pound (#) sign).", + "type": "string" + }, + "match": { + "description": "A regular expression which is used to identify the portion of text to which the name should be assigned.", + "type": "string" + }, + "begin": { + "description": "The `begin` key is a regular expression pattern that allows matches which span several lines. Captures from the `begin` pattern can be referenced in the corresponding `end` or `while` pattern by using normal regular expression back-references, eg. `\\1$`.", + "type": "string" + }, + "end": { + "description": "A regular expression pattern that, when matched, ends the multi-line block started by the `begin` key.", + "type": "string" + }, + "while": { + "description": "A regular expression pattern that, while matched, continues the multi-line block started by the `begin` key.", + "type": "string" + }, + "applyEndPatternLast": { + "description": "Tests the `end` pattern after the other patterns in the `begin`/`end` block.", + "$ref": "#/definitions/boolean-or-integer" + }, + "contentName": { + "description": "This key is similar to the `name` key but it only assigns the name to the text between what is matched by the `begin`/`end` patterns.", + "type": "string" + }, + "captures": { + "description": "This key allows you to assign attributes to the captures of the `match`, `begin`, `end` and `while`patterns. Using the `captures` key for a `begin`/`end` rule is short-hand for giving both `beginCaptures` and `endCaptures` with same values. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text.", + "$ref": "#/definitions/captures" + }, + "beginCaptures": { + "description": "This key allows you to assign attributes to the captures of the `begin` pattern. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text.", + "$ref": "#/definitions/captures" + }, + "endCaptures": { + "description": "This key allows you to assign attributes to the captures of the `end` pattern. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text.", + "$ref": "#/definitions/captures" + }, + "whileCaptures": { + "description": "This key allows you to assign attributes to the captures of the `while` pattern. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text.", + "$ref": "#/definitions/captures" + }, + "patterns": { + "description": "An array with the actual rules used to parse the matched content.", + "$ref": "#/definitions/patterns" + }, + "repository": { + "description": "A dictionary (i.e. key/value pairs) of rules which can be included from other places in the grammar. The key is the name of the rule and the value is the actual rule.", + "$ref": "#/definitions/repository" + } + }, + "additionalProperties": false, + "dependencies": { + "include": { + "allOf": [ + { + "not": { + "required": [ + "match" + ] + } + }, + { + "not": { + "required": [ + "begin" + ] + } + } + ] + }, + "match": { + "not": { + "required": [ + "begin" + ] + } + }, + "begin": { + "oneOf": [ + { + "required": [ + "end" + ] + }, + { + "required": [ + "while" + ] + } + ] + }, + "end": [ + "begin" + ], + "while": [ + "begin" + ], + "applyEndPatternLast": [ + "begin" + ], + "captures": { + "oneOf": [ + { + "required": [ + "match" + ] + }, + { + "required": [ + "begin" + ] + } + ] + }, + "beginCaptures": [ + "begin" + ], + "endCaptures": [ + "end" + ], + "whileCaptures": [ + "while" + ] + } + } + } +} \ No newline at end of file diff --git a/syntax/src/typescript/GenerateTmLanguageFile.ts b/syntax/src/typescript/GenerateTmLanguageFile.ts new file mode 100644 index 0000000..72b7d65 --- /dev/null +++ b/syntax/src/typescript/GenerateTmLanguageFile.ts @@ -0,0 +1,23 @@ +"use strict"; + +import * as fs from 'fs'; +import * as Ajv from 'ajv'; +import { scalaTmLanguage } from "./Scala.tmLanguage"; + +let schema = fs.readFileSync('./src/schemas/tmlanguage.json').toString(); + +var ajv = new Ajv({verbose: true}); +ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json')); + +var validate = ajv.compile(JSON.parse(schema)); +var valid = validate(scalaTmLanguage); +if (!valid) { + console.error("The were validation errors.\n"); + console.error(validate.errors); +} else { + console.log(JSON.stringify(scalaTmLanguage)); +} + + + + diff --git a/syntax/src/typescript/Scala.tmLanguage.ts b/syntax/src/typescript/Scala.tmLanguage.ts new file mode 100644 index 0000000..63b2024 --- /dev/null +++ b/syntax/src/typescript/Scala.tmLanguage.ts @@ -0,0 +1,822 @@ +"use strict"; +import { TmLanguage } from "./TMLanguageModel"; + +export const scalaTmLanguage: TmLanguage = { + fileTypes: [ + 'scala' + ], + firstLineMatch: '^#!/.*\\b\\w*scala\\b', + foldingStartMarker: '/\\*\\*|\\{\\s*$', + foldingStopMarker: '\\*\\*/|^\\s*\\}', + keyEquivalent: '^~S', + repository: { + 'empty-parentheses': { + match: '(\\(\\))', + captures: { + '1': { + name: 'meta.bracket.scala' + } + }, + name: 'meta.parentheses.scala' + }, + imports: { + end: '(?<=[\\n;])', + begin: '\\b(import)\\s+', + beginCaptures: { + '1': { + name: 'keyword.other.import.scala' + } + }, + patterns: [ + { + include: '#comments' + }, + { + match: '(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*)', + name: 'entity.name.import.scala' + }, + { + match: '\\.', + name: 'punctuation.definition.import' + }, + { + end: '}', + begin: '{', + beginCaptures: { + '0': { + name: 'meta.bracket.scala' + } + }, + patterns: [ + { + match: '(?x) \\s*\n\t\t\t\t (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) \\s*\n\t\t\t\t (=>) \\s*\n\t\t\t\t (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) \\s*\n\t\t\t ', + captures: { + '1': { + name: 'entity.name.import.renamed-from.scala' + }, + '2': { + name: 'keyword.other.arrow.scala' + }, + '3': { + name: 'entity.name.import.renamed-to.scala' + } + } + }, + { + match: '([^\\s.,}]+)', + name: 'entity.name.import.scala' + } + ], + endCaptures: { + '0': { + name: 'meta.bracket.scala' + } + }, + name: 'meta.import.selector.scala' + } + ], + name: 'meta.import.scala' + }, + constants: { + patterns: [ + { + match: '\\b(false|null|true|Nil|None)\\b', + name: 'constant.language.scala' + }, + { + match: '\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.[0-9]+)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?|[0-9]+)([LlFfDd]|UL|ul)?\\b', + name: 'constant.numeric.scala' + }, + { + match: '\\b(this|super|self)\\b', + name: 'variable.language.scala' + }, + { + match: '\\b(Unit|Boolean|Byte|Char|Short|Int|Float|Long|Double)\\b', + name: 'storage.type.primitive.scala' + }, + { + match: '\\b(String|Symbol)\\b', + name: 'storage.type.scala' + } + ] + }, + 'block-comments': { + end: '\\*/', + begin: '/\\*', + patterns: [ + { + include: '#block-comments' + }, + { + match: '(?x)\n\t\t\t(?! /\\*)\n\t\t\t(?! \\*/)\n\t\t ' + } + ], + name: 'comment.block.scala' + }, + 'script-header': { + match: '^#!(.*)$', + captures: { + '1': { + name: 'string.unquoted.shebang.scala' + } + }, + name: 'comment.block.shebang.scala' + }, + code: { + patterns: [ + { + include: '#script-header' + }, + { + include: '#storage-modifiers' + }, + { + include: '#declarations' + }, + { + include: '#inheritance' + }, + { + include: '#imports' + }, + { + include: '#comments' + }, + { + include: '#strings' + }, + { + include: '#initialization' + }, + { + include: '#xml-literal' + }, + { + include: '#keywords' + }, + { + include: '#constants' + }, + { + include: '#scala-symbol' + }, + { + include: '#scala-quoted' + }, + { + include: '#special-identifier' + }, + { + include: '#char-literal' + }, + { + include: '#empty-parentheses' + }, + { + include: '#parameter-list' + }, + { + include: '#qualifiedClassName' + }, + { + include: '#meta-brackets' + }, + { + include: '#meta-bounds' + }, + { + include: '#meta-colons' + } + ] + }, + 'special-identifier': { + match: '\\b[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\\t .,;()\\[\\]{}\'"`\\w])', + comment: '\n\t\t Match special scala style identifiers that can end with and underscore and\n\t\t a a not letter such as blank_?. This way the symbol will not be colored\n\t\t differently.\n\t\t ' + }, + strings: { + patterns: [ + { + end: '"""(?!")', + begin: '"""', + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.scala' + } + }, + patterns: [ + { + match: '\\\\\\\\|\\\\u[0-9A-Fa-f]{4}', + name: 'constant.character.escape.scala' + } + ], + endCaptures: { + '0': { + name: 'punctuation.definition.string.end.scala' + } + }, + name: 'string.quoted.triple.scala' + }, + { + end: '"', + begin: '"', + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.scala' + } + }, + patterns: [ + { + match: `\\\\(?:[btnfr\\\\"']|[0-7]{1,3}|u[0-9A-Fa-f]{4})`, + name: 'constant.character.escape.scala' + }, + { + match: '\\\\.', + name: 'invalid.illegal.unrecognized-string-escape.scala' + } + ], + endCaptures: { + '0': { + name: 'punctuation.definition.string.end.scala' + } + }, + name: 'string.quoted.double.scala' + } + ] + }, + 'xml-entity': { + match: '(&)([:a-zA-Z_][:a-zA-Z0-9_.-]*|#[0-9]+|#x[0-9a-fA-F]+)(;)', + captures: { + '1': { + name: 'punctuation.definition.constant.xml' + }, + '3': { + name: 'punctuation.definition.constant.xml' + } + }, + name: 'constant.character.entity.xml' + }, + 'xml-singlequotedString': { + end: "'", + begin: "'", + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.xml' + } + }, + patterns: [ + { + include: '#xml-entity' + } + ], + endCaptures: { + '0': { + name: 'punctuation.definition.string.end.xml' + } + }, + name: 'string.quoted.single.xml' + }, + 'meta-colons': { + patterns: [ + { + match: '(?=|<>|<|>)', + name: 'keyword.operator.comparison.scala' + }, + { + match: '(\\-|\\+|\\*|/(?![/*])|%|~)', + name: 'keyword.operator.arithmetic.scala' + }, + { + match: '(!|&&|\\|\\|)', + name: 'keyword.operator.logical.scala' + }, + { + match: '(<-|←|->|→|=>|⇒|\\?|\\:+|@|\\|)+', + name: 'keyword.operator.scala' + } + ] + }, + 'scala-quoted': { + match: "'\\{'|'\\('|'\\['|'\\{|'\\(|'\\[", + name: 'constant.other.quoted.scala' + }, + 'xml-doublequotedString': { + end: '"', + begin: '"', + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.xml' + } + }, + patterns: [ + { + include: '#xml-entity' + } + ], + endCaptures: { + '0': { + name: 'punctuation.definition.string.end.xml' + } + }, + name: 'string.quoted.double.xml' + }, + declarations: { + patterns: [ + { + match: '(?x)\n\t\t\t\t\t\t\\b(def)\\s+\n\t\t\t\t\t\t(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\\t .,;()\\[\\]{}\'"`\\w])(?=[(\\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\\\]+)', + captures: { + '1': { + name: 'keyword.declaration.scala' + }, + '2': { + name: 'entity.name.function.declaration' + } + } + }, + { + match: '\\b(trait)\\s+([^\\s\\{\\(\\[]+)', + captures: { + '1': { + name: 'keyword.declaration.scala' + }, + '2': { + name: 'entity.name.class.declaration' + } + } + }, + { + match: '\\b(?:(case)\\s+)?(class|object)\\s+([^\\s\\{\\(\\[]+)', + captures: { + '1': { + name: 'keyword.declaration.scala' + }, + '2': { + name: 'keyword.declaration.scala' + }, + '3': { + name: 'entity.name.class.declaration' + } + } + }, + { + match: '\\b(type)\\s+(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\\s])(?=[\\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\\\]+)', + captures: { + '1': { + name: 'keyword.declaration.scala' + }, + '2': { + name: 'entity.name.type.declaration' + } + } + }, + { + match: '\\b(val)\\s+(?:([A-Z][_a-zA-Z0-9]*))\\b', + captures: { + '1': { + name: 'keyword.declaration.stable.scala' + }, + '2': { + name: 'constant.other.declaration.scala' + } + } + }, + { + match: '\\b(?:(val)|(var))\\s+(?:(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\\t .,;()\\[\\]{}\'"`\\w])(?=[\\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\\\]+)|(?=\\())', + captures: { + '1': { + name: 'keyword.declaration.stable.scala' + }, + '2': { + name: 'keyword.declaration.volatile.scala' + }, + '3': { + name: 'variable.other.declaration.scala' + } + } + }, + { + match: '\\b(package)\\s+(object)\\s+([^\\s\\{\\(\\[]+)', + captures: { + '1': { + name: 'keyword.other.scoping.scala' + }, + '2': { + name: 'keyword.declaration.scala' + }, + '3': { + name: 'entity.name.class.declaration' + } + } + }, + { + end: '(?<=[\\n;])', + begin: '\\b(package)\\s+', + beginCaptures: { + '1': { + name: 'keyword.other.import.scala' + } + }, + patterns: [ + { + include: '#comments' + }, + { + match: '(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*)', + name: 'entity.name.package.scala' + }, + { + match: '\\.', + name: 'punctuation.definition.package' + } + ], + name: 'meta.package.scala' + } + ] + }, + 'char-literal': { + end: "'", + begin: "'", + beginCaptures: { + '0': { + name: 'punctuation.definition.character.begin.scala' + } + }, + patterns: [ + { + match: `\\\\(?:[btnfr\\\\"']|[0-7]{1,3}|u[0-9A-Fa-f]{4})`, + name: 'constant.character.escape.scala' + }, + { + match: '\\\\.', + name: 'invalid.illegal.unrecognized-character-escape.scala' + }, + { + match: "[^']{2,}", + name: 'invalid.illegal.character-literal-too-long' + }, + { + match: "(?:|<:', + comment: 'For themes: Matching view bounds', + name: 'meta.bounds.scala' + }, + comments: { + patterns: [ + { + match: '/\\*\\*/', + captures: { + '0': { + name: 'punctuation.definition.comment.scala' + } + }, + name: 'comment.block.empty.scala' + }, + { + end: '\\*/', + begin: '^\\s*(/\\*\\*)(?!/)', + beginCaptures: { + '1': { + name: 'punctuation.definition.comment.scala' + } + }, + patterns: [ + { + match: '(@param)\\s+(\\S+)', + captures: { + '1': { + name: 'keyword.other.documentation.scaladoc.scala' + }, + '2': { + name: 'variable.parameter.scala' + } + } + }, + { + match: '(@(?:tparam|throws))\\s+(\\S+)', + captures: { + '1': { + name: 'keyword.other.documentation.scaladoc.scala' + }, + '2': { + name: 'entity.name.class' + } + } + }, + { + match: '@(return|see|note|example|usecase|author|version|since|todo|deprecated|migration|define|inheritdoc)\\b', + name: 'keyword.other.documentation.scaladoc.scala' + }, + { + match: '(\\[\\[)([^\\]]+)(\\]\\])', + captures: { + '1': { + name: 'punctuation.definition.documentation.link.scala' + }, + '2': { + name: 'entity.other.documentation.link.scala' + }, + '3': { + name: 'punctuation.definition.documentation.link.scala' + } + } + } + ], + endCaptures: { + '0': { + name: 'punctuation.definition.comment.scala' + } + }, + name: 'comment.block.documentation.scala' + }, + { + end: '\\*/', + begin: '/\\*', + captures: { + '0': { + name: 'punctuation.definition.comment.scala' + } + }, + name: 'comment.block.scala' + }, + { + end: '(?!\\G)', + begin: '(^[ \\t]+)?(?=//)', + beginCaptures: { + '1': { + name: 'punctuation.whitespace.comment.leading.scala' + } + }, + patterns: [ + { + end: '\\n', + begin: '//', + beginCaptures: { + '0': { + name: 'punctuation.definition.comment.scala' + } + }, + name: 'comment.line.double-slash.scala' + } + ] + } + ] + }, + 'xml-embedded-content': { + patterns: [ + { + end: '}', + begin: '{', + patterns: [ + { + include: '#code' + } + ], + captures: { + '0': { + name: 'meta.bracket.scala' + } + }, + name: 'meta.source.embedded.scala' + }, + { + match: ' (?:([-_a-zA-Z0-9]+)((:)))?([_a-zA-Z-]+)=', + captures: { + '1': { + name: 'entity.other.attribute-name.namespace.xml' + }, + '2': { + name: 'entity.other.attribute-name.xml' + }, + '3': { + name: 'punctuation.separator.namespace.xml' + }, + '4': { + name: 'entity.other.attribute-name.localname.xml' + } + } + }, + { + include: '#xml-doublequotedString' + }, + { + include: '#xml-singlequotedString' + } + ] + }, + inheritance: { + patterns: [ + { + match: '(extends|with)\\s+([^\\s\\{\\(\\[\\]]+)', + captures: { + '1': { + name: 'keyword.declaration.scala' + }, + '2': { + name: 'entity.other.inherited-class.scala' + } + } + } + ] + }, + 'parameter-list': { + patterns: [ + { + match: '(?<=[^\\._$a-zA-Z0-9])(`[^`]+`|[_$a-z][_$a-zA-Z0-9]*(?:_[^\\s])(?=[\\t ])|[_$a-z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\\\]+)\\s*(:)\\s+', + captures: { + '1': { + name: 'variable.parameter.scala' + }, + '2': { + name: 'meta.colon.scala' + } + }, + comment: 'We do not match param names that start with a Capitol letter' + } + ] + }, + 'xml-literal': { + patterns: [ + { + end: '(>(<))/(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]*[_a-zA-Z0-9])(>)', + begin: '(<)((?:([_a-zA-Z0-9][_a-zA-Z0-9]*)((:)))?([_a-zA-Z0-9][-_a-zA-Z0-9:]*))(?=(\\s[^>]*)?>)', + beginCaptures: { + '1': { + name: 'punctuation.definition.tag.xml' + }, + '3': { + name: 'entity.name.tag.namespace.xml' + }, + '4': { + name: 'entity.name.tag.xml' + }, + '5': { + name: 'punctuation.separator.namespace.xml' + }, + '6': { + name: 'entity.name.tag.localname.xml' + } + }, + patterns: [ + { + include: '#xml-embedded-content' + } + ], + comment: 'We do not allow a tag name to start with a - since this would\n\t\t\t\t likely conflict with the <- operator. This is not very common\n\t\t\t\t for tag names anyway. Also code such as -- if (val val3)\n\t\t\t\t will falsly be recognized as an xml tag. The solution is to put a\n\t\t\t\t space on either side of the comparison operator', + endCaptures: { + '1': { + name: 'punctuation.definition.tag.xml' + }, + '2': { + name: 'meta.scope.between-tag-pair.xml' + }, + '3': { + name: 'entity.name.tag.namespace.xml' + }, + '4': { + name: 'entity.name.tag.xml' + }, + '5': { + name: 'punctuation.separator.namespace.xml' + }, + '6': { + name: 'entity.name.tag.localname.xml' + }, + '7': { + name: 'punctuation.definition.tag.xml' + } + }, + name: 'meta.tag.no-content.xml' + }, + { + end: '(/?>)', + begin: '(]*?>)', + patterns: [ + { + include: '#xml-embedded-content' + } + ], + captures: { + '1': { + name: 'punctuation.definition.tag.xml' + }, + '2': { + name: 'entity.name.tag.namespace.xml' + }, + '3': { + name: 'entity.name.tag.xml' + }, + '4': { + name: 'punctuation.separator.namespace.xml' + }, + '5': { + name: 'entity.name.tag.localname.xml' + } + }, + name: 'meta.tag.xml' + }, + { + include: '#xml-entity' + } + ] + } + }, + uuid: '158C0929-299A-40C8-8D89-316BE0C446E8', + "$schema" : "https://raw.githubusercontent.com/Septh/tmlanguage/master/tmLanguage.schema.json", + patterns: [ + { + include: '#code' + } + ], + name: 'Scala', + scopeName: 'source.scala' +} diff --git a/syntax/src/typescript/TMLanguageModel.ts b/syntax/src/typescript/TMLanguageModel.ts new file mode 100644 index 0000000..e6e5a9f --- /dev/null +++ b/syntax/src/typescript/TMLanguageModel.ts @@ -0,0 +1,222 @@ +/* tslint:disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +/** + * Schema for language grammar description files in Textmate and compatible editors. + */ +export interface TmLanguage { + /** + * This should be a unique name for the grammar, following the convention of being a dot-separated name where each new (left-most) part specializes the name. Normally it would be a two-part name where the first is either `text` or `source` and the second is the name of the language or document type. But if you are specializing an existing type, you probably want to derive the name from the type you are specializing. For example Markdown is `text.html.markdown` and Ruby on Rails (rhtml files) is `text.html.rails`. The advantage of deriving it from (in this case) `text.html` is that everything which works in the `text.html` scope will also work in the `text.html.«something»` scope (but with a lower precedence than something specifically targeting `text.html.«something»`). + */ + scopeName: string; + /** + * An array of file type extensions that the grammar should (by default) be used with. + */ + fileTypes?: string[]; + /** + * A regular expression which is matched against the first line of the document when it is first loaded. If it matches, the grammar is used for the document. + */ + firstLineMatch?: string; + /** + * When the grammer is part of a larger bundle (ie., grammer + theme + whatever), the uuid helps classify which file is a part of which bundle. + */ + uuid?: string; + /** + * Regular expression that lines (in the document) are matched against. If a line matches the pattern, it starts a foldable block. + */ + foldingStartMarker?: string; + /** + * Regular expressions that lines (in the document) are matched against. If a line matches pattern, it ends a foldable block. + */ + foldingStopMarker?: string; + /** + * An array with the actual rules used to parse the document. + */ + patterns: Rule[]; + /** + * A dictionary (i.e. key/value pairs) of rules which can be included from other places in the grammar. The key is the name of the rule and the value is the actual rule. + */ + repository?: { + [k: string]: Rule; + }; + /** + * The key is a scope selector that specifies which scope(s) the current grammar should be injected in. + */ + injectionSelector?: string; + /** + * [VS Code only, it seems] A dictionary (i.e. key/value pairs) of rules which will be injected into an existing grammar. The key is the target scope of the parent grammar and the value is the actual rule to inject. + */ + injections?: { + [k: string]: Rule; + }; + [k: string]: any; + } + export interface Rule { + /** + * A generic text used to describe or explain the rule. + */ + comment?: string; + /** + * The scope name which gets assigned to the capture matched. This should generally be derived from one of the standard names. + */ + name?: string; + /** + * Marks the rule as disabled. A disabled rule should be ignored by the tokenization engine. + */ + disabled?: boolean | (0 | 1); + /** + * This key allows you to reference a different language (value == scope name), recursively reference the grammar itself (value == "$self") or a rule declared in this file’s repository (value starts with a pound (#) sign). + */ + include?: string; + /** + * A regular expression which is used to identify the portion of text to which the name should be assigned. + */ + match?: string; + /** + * The `begin` key is a regular expression pattern that allows matches which span several lines. Captures from the `begin` pattern can be referenced in the corresponding `end` or `while` pattern by using normal regular expression back-references, eg. `\1$`. + */ + begin?: string; + /** + * A regular expression pattern that, when matched, ends the multi-line block started by the `begin` key. + */ + end?: string; + /** + * A regular expression pattern that, while matched, continues the multi-line block started by the `begin` key. + */ + while?: string; + /** + * Tests the `end` pattern after the other patterns in the `begin`/`end` block. + */ + applyEndPatternLast?: boolean | (0 | 1); + /** + * This key is similar to the `name` key but it only assigns the name to the text between what is matched by the `begin`/`end` patterns. + */ + contentName?: string; + /** + * This key allows you to assign attributes to the captures of the `match`, `begin`, `end` and `while`patterns. Using the `captures` key for a `begin`/`end` rule is short-hand for giving both `beginCaptures` and `endCaptures` with same values. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text. + */ + captures?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + */ + [k: string]: { + /** + * The scope name which gets assigned to the capture matched. This should generally be derived from one of the standard names. + */ + name?: string; + /** + * Yes, captures can be further matched against additional patterns, too. + */ + patterns?: Rule[]; + }; + }; + /** + * This key allows you to assign attributes to the captures of the `begin` pattern. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text. + */ + beginCaptures?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + */ + [k: string]: { + /** + * The scope name which gets assigned to the capture matched. This should generally be derived from one of the standard names. + */ + name?: string; + /** + * Yes, captures can be further matched against additional patterns, too. + */ + patterns?: Rule[]; + }; + }; + /** + * This key allows you to assign attributes to the captures of the `end` pattern. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text. + */ + endCaptures?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + */ + [k: string]: { + /** + * The scope name which gets assigned to the capture matched. This should generally be derived from one of the standard names. + */ + name?: string; + /** + * Yes, captures can be further matched against additional patterns, too. + */ + patterns?: Rule[]; + }; + }; + /** + * This key allows you to assign attributes to the captures of the `while` pattern. The value of this key is a dictionary with the key being the capture number and the value being a dictionary of attributes to assign to the captured text. + */ + whileCaptures?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[0-9]+$". + */ + [k: string]: { + /** + * The scope name which gets assigned to the capture matched. This should generally be derived from one of the standard names. + */ + name?: string; + /** + * Yes, captures can be further matched against additional patterns, too. + */ + patterns?: Rule[]; + }; + }; + /** + * An array with the actual rules used to parse the matched content. + */ + patterns?: Rule[]; + /** + * A dictionary (i.e. key/value pairs) of rules which can be included from other places in the grammar. The key is the name of the rule and the value is the actual rule. + */ + repository?: { + [k: string]: Rule; + }; + } + \ No newline at end of file diff --git a/syntax/syntaxes/.gitkeep b/syntax/syntaxes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/syntax/syntaxes/Scala.tmLanguage b/syntax/syntaxes/Scala.tmLanguage deleted file mode 100644 index dbbb975..0000000 --- a/syntax/syntaxes/Scala.tmLanguage +++ /dev/null @@ -1,1290 +0,0 @@ - - - - - fileTypes - - scala - - firstLineMatch - ^#!/.*\b\w*scala\b - foldingStartMarker - /\*\*|\{\s*$ - foldingStopMarker - \*\*/|^\s*\} - keyEquivalent - ^~S - name - Scala - patterns - - - include - #code - - - repository - - block-comments - - begin - /\* - end - \*/ - name - comment.block.scala - patterns - - - include - #block-comments - - - match - (?x) - (?! /\*) - (?! \*/) - - - - - char-literal - - begin - ' - beginCaptures - - 0 - - name - punctuation.definition.character.begin.scala - - - end - ' - endCaptures - - 0 - - name - punctuation.definition.character.end.scala - - - name - constant.character.literal.scala - patterns - - - match - \\(?:[btnfr\\"']|[0-7]{1,3}|u[0-9A-Fa-f]{4}) - name - constant.character.escape.scala - - - match - \\. - name - invalid.illegal.unrecognized-character-escape.scala - - - match - [^']{2,} - name - invalid.illegal.character-literal-too-long - - - match - (?<!')[^'] - name - invalid.illegal.character-literal-too-long - - - - code - - patterns - - - include - #script-header - - - include - #storage-modifiers - - - include - #declarations - - - include - #inheritance - - - include - #imports - - - include - #comments - - - include - #strings - - - include - #initialization - - - include - #xml-literal - - - include - #keywords - - - include - #constants - - - include - #scala-symbol - - - include - #scala-quoted - - - include - #special-identifier - - - include - #char-literal - - - include - #empty-parentheses - - - include - #parameter-list - - - include - #qualifiedClassName - - - include - #meta-brackets - - - include - #meta-bounds - - - include - #meta-colons - - - - comments - - patterns - - - captures - - 0 - - name - punctuation.definition.comment.scala - - - match - /\*\*/ - name - comment.block.empty.scala - - - begin - ^\s*(/\*\*)(?!/) - beginCaptures - - 1 - - name - punctuation.definition.comment.scala - - - end - \*/ - endCaptures - - 0 - - name - punctuation.definition.comment.scala - - - name - comment.block.documentation.scala - patterns - - - captures - - 1 - - name - keyword.other.documentation.scaladoc.scala - - 2 - - name - variable.parameter.scala - - - match - (@param)\s+(\S+) - - - captures - - 1 - - name - keyword.other.documentation.scaladoc.scala - - 2 - - name - entity.name.class - - - match - (@(?:tparam|throws))\s+(\S+) - - - match - @(return|see|note|example|usecase|author|version|since|todo|deprecated|migration|define|inheritdoc)\b - name - keyword.other.documentation.scaladoc.scala - - - captures - - 1 - - name - punctuation.definition.documentation.link.scala - - 2 - - name - entity.other.documentation.link.scala - - 3 - - name - punctuation.definition.documentation.link.scala - - - match - (\[\[)([^\]]+)(\]\]) - - - - - begin - /\* - captures - - 0 - - name - punctuation.definition.comment.scala - - - end - \*/ - name - comment.block.scala - - - begin - (^[ \t]+)?(?=//) - beginCaptures - - 1 - - name - punctuation.whitespace.comment.leading.scala - - - end - (?!\G) - patterns - - - begin - // - beginCaptures - - 0 - - name - punctuation.definition.comment.scala - - - end - \n - name - comment.line.double-slash.scala - - - - - - constants - - patterns - - - match - \b(false|null|true|Nil|None)\b - name - constant.language.scala - - - match - \b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.[0-9]+)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?|[0-9]+)([LlFfDd]|UL|ul)?\b - name - constant.numeric.scala - - - match - \b(this|super|self)\b - name - variable.language.scala - - - match - \b(Unit|Boolean|Byte|Char|Short|Int|Float|Long|Double)\b - name - storage.type.primitive.scala - - - match - \b(String|Symbol)\b - name - storage.type.scala - - - - declarations - - patterns - - - captures - - 1 - - name - keyword.declaration.scala - - 2 - - name - entity.name.function.declaration - - - match - (?x) - \b(def)\s+ - (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\t .,;()\[\]{}'"`\w])(?=[(\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+) - - - captures - - 1 - - name - keyword.declaration.scala - - 2 - - name - entity.name.class.declaration - - - match - \b(trait)\s+([^\s\{\(\[]+) - - - captures - - 1 - - name - keyword.declaration.scala - - 2 - - name - keyword.declaration.scala - - 3 - - name - entity.name.class.declaration - - - match - \b(?:(case)\s+)?(class|object)\s+([^\s\{\(\[]+) - - - captures - - 1 - - name - keyword.declaration.scala - - 2 - - name - entity.name.type.declaration - - - match - \b(type)\s+(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\s])(?=[\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+) - - - captures - - 1 - - name - keyword.declaration.stable.scala - - 2 - - name - constant.other.declaration.scala - - - match - \b(val)\s+(?:([A-Z][_a-zA-Z0-9]*))\b - - - captures - - 1 - - name - keyword.declaration.stable.scala - - 2 - - name - keyword.declaration.volatile.scala - - 3 - - name - variable.other.declaration.scala - - - match - \b(?:(val)|(var))\s+(?:(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\t .,;()\[\]{}'"`\w])(?=[\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+)|(?=\()) - - - captures - - 1 - - name - keyword.other.scoping.scala - - 2 - - name - keyword.declaration.scala - - 3 - - name - entity.name.class.declaration - - - match - \b(package)\s+(object)\s+([^\s\{\(\[]+) - - - begin - \b(package)\s+ - beginCaptures - - 1 - - name - keyword.other.import.scala - - - end - (?<=[\n;]) - name - meta.package.scala - patterns - - - include - #comments - - - match - (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) - name - entity.name.package.scala - - - match - \. - name - punctuation.definition.package - - - - - - empty-parentheses - - captures - - 1 - - name - meta.bracket.scala - - - match - (\(\)) - name - meta.parentheses.scala - - imports - - begin - \b(import)\s+ - beginCaptures - - 1 - - name - keyword.other.import.scala - - - end - (?<=[\n;]) - name - meta.import.scala - patterns - - - include - #comments - - - match - (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) - name - entity.name.import.scala - - - match - \. - name - punctuation.definition.import - - - begin - { - beginCaptures - - 0 - - name - meta.bracket.scala - - - end - } - endCaptures - - 0 - - name - meta.bracket.scala - - - name - meta.import.selector.scala - patterns - - - captures - - 1 - - name - entity.name.import.renamed-from.scala - - 2 - - name - keyword.other.arrow.scala - - 3 - - name - entity.name.import.renamed-to.scala - - - match - (?x) \s* - (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) \s* - (=>) \s* - (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) \s* - - - - match - ([^\s.,}]+) - name - entity.name.import.scala - - - - - - inheritance - - patterns - - - captures - - 1 - - name - keyword.declaration.scala - - 2 - - name - entity.other.inherited-class.scala - - - match - (extends|with)\s+([^\s\{\(\[\]]+) - - - - initialization - - captures - - 1 - - name - keyword.declaration.scala - - 2 - - name - entity.name.class - - - match - \b(new)\s+([^\s,\{\}\(\)\[\]]+) - - keywords - - patterns - - - match - \b(return|throw)\b - name - keyword.control.flow.jump.scala - - - match - \b(classOf|isInstanceOf|asInstanceOf)\b - name - support.function.type-of.scala - - - match - \b(else|if|do|while|for|yield|match|case)\b - name - keyword.control.flow.scala - - - match - \b(catch|finally|try)\b - name - keyword.control.exception.scala - - - match - (==?|!=|<=|>=|<>|<|>) - name - keyword.operator.comparison.scala - - - match - (\-|\+|\*|/(?![/*])|%|~) - name - keyword.operator.arithmetic.scala - - - match - (!|&&|\|\|) - name - keyword.operator.logical.scala - - - match - (<-|←|->|→|=>|⇒|\?|\:+|@|\|)+ - name - keyword.operator.scala - - - - meta-bounds - - comment - For themes: Matching view bounds - match - <%|=:=|<:<|<%<|>:|<: - name - meta.bounds.scala - - meta-brackets - - comment - For themes: Brackets look nice when colored. - patterns - - - comment - The punctuation.section.*.begin is needed for return snippet in source bundle - match - \{ - name - punctuation.section.block.begin.scala - - - comment - The punctuation.section.*.end is needed for return snippet in source bundle - match - \} - name - punctuation.section.block.end.scala - - - match - {|}|\(|\)|\[|\] - name - meta.bracket.scala - - - - meta-colons - - comment - For themes: Matching type colons - patterns - - - match - (?<!:):(?!:) - name - meta.colon.scala - - - - parameter-list - - patterns - - - captures - - 1 - - name - variable.parameter.scala - - 2 - - name - meta.colon.scala - - - comment - We do not match param names that start with a Capitol letter - match - (?<=[^\._$a-zA-Z0-9])(`[^`]+`|[_$a-z][_$a-zA-Z0-9]*(?:_[^\s])(?=[\t ])|[_$a-z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+)\s*(:)\s+ - - - - qualifiedClassName - - captures - - 1 - - name - entity.name.class - - - match - (\b([A-Z][\w]*)) - - scala-symbol - - match - '\w+(?=[^'\w]|$) - name - constant.other.symbol.scala - - scala-quoted - - match - '\{'|'\('|'\['|'\{|'\(|'\[ - name - constant.other.quoted.scala - - script-header - - captures - - 1 - - name - string.unquoted.shebang.scala - - - match - ^#!(.*)$ - name - comment.block.shebang.scala - - special-identifier - - comment - - Match special scala style identifiers that can end with and underscore and - a a not letter such as blank_?. This way the symbol will not be colored - differently. - - match - \b[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\t .,;()\[\]{}'"`\w]) - - storage-modifiers - - patterns - - - match - \b(private\[\S+\]|protected\[\S+\]|private|protected)\b - name - storage.modifier.access - - - match - \b(synchronized|@volatile|abstract|final|lazy|sealed|implicit|override|@transient|@native)\b - name - storage.modifier.other - - - - strings - - patterns - - - begin - """ - beginCaptures - - 0 - - name - punctuation.definition.string.begin.scala - - - end - """(?!") - endCaptures - - 0 - - name - punctuation.definition.string.end.scala - - - name - string.quoted.triple.scala - patterns - - - match - \\\\|\\u[0-9A-Fa-f]{4} - name - constant.character.escape.scala - - - - - begin - " - beginCaptures - - 0 - - name - punctuation.definition.string.begin.scala - - - end - " - endCaptures - - 0 - - name - punctuation.definition.string.end.scala - - - name - string.quoted.double.scala - patterns - - - match - \\(?:[btnfr\\"']|[0-7]{1,3}|u[0-9A-Fa-f]{4}) - name - constant.character.escape.scala - - - match - \\. - name - invalid.illegal.unrecognized-string-escape.scala - - - - - - xml-doublequotedString - - begin - " - beginCaptures - - 0 - - name - punctuation.definition.string.begin.xml - - - end - " - endCaptures - - 0 - - name - punctuation.definition.string.end.xml - - - name - string.quoted.double.xml - patterns - - - include - #xml-entity - - - - xml-embedded-content - - patterns - - - begin - { - captures - - 0 - - name - meta.bracket.scala - - - end - } - name - meta.source.embedded.scala - patterns - - - include - #code - - - - - captures - - 1 - - name - entity.other.attribute-name.namespace.xml - - 2 - - name - entity.other.attribute-name.xml - - 3 - - name - punctuation.separator.namespace.xml - - 4 - - name - entity.other.attribute-name.localname.xml - - - match - (?:([-_a-zA-Z0-9]+)((:)))?([_a-zA-Z-]+)= - - - include - #xml-doublequotedString - - - include - #xml-singlequotedString - - - - xml-entity - - captures - - 1 - - name - punctuation.definition.constant.xml - - 3 - - name - punctuation.definition.constant.xml - - - match - (&)([:a-zA-Z_][:a-zA-Z0-9_.-]*|#[0-9]+|#x[0-9a-fA-F]+)(;) - name - constant.character.entity.xml - - xml-literal - - patterns - - - begin - (<)((?:([_a-zA-Z0-9][_a-zA-Z0-9]*)((:)))?([_a-zA-Z0-9][-_a-zA-Z0-9:]*))(?=(\s[^>]*)?></\2>) - beginCaptures - - 1 - - name - punctuation.definition.tag.xml - - 3 - - name - entity.name.tag.namespace.xml - - 4 - - name - entity.name.tag.xml - - 5 - - name - punctuation.separator.namespace.xml - - 6 - - name - entity.name.tag.localname.xml - - - comment - We do not allow a tag name to start with a - since this would - likely conflict with the <- operator. This is not very common - for tag names anyway. Also code such as -- if (val <val2 || val> val3) - will falsly be recognized as an xml tag. The solution is to put a - space on either side of the comparison operator - end - (>(<))/(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]*[_a-zA-Z0-9])(>) - endCaptures - - 1 - - name - punctuation.definition.tag.xml - - 2 - - name - meta.scope.between-tag-pair.xml - - 3 - - name - entity.name.tag.namespace.xml - - 4 - - name - entity.name.tag.xml - - 5 - - name - punctuation.separator.namespace.xml - - 6 - - name - entity.name.tag.localname.xml - - 7 - - name - punctuation.definition.tag.xml - - - name - meta.tag.no-content.xml - patterns - - - include - #xml-embedded-content - - - - - begin - (</?)(?:([_a-zA-Z0-9][-_a-zA-Z0-9]*)((:)))?([_a-zA-Z0-9][-_a-zA-Z0-9:]*)(?=[^>]*?>) - captures - - 1 - - name - punctuation.definition.tag.xml - - 2 - - name - entity.name.tag.namespace.xml - - 3 - - name - entity.name.tag.xml - - 4 - - name - punctuation.separator.namespace.xml - - 5 - - name - entity.name.tag.localname.xml - - - end - (/?>) - name - meta.tag.xml - patterns - - - include - #xml-embedded-content - - - - - include - #xml-entity - - - - xml-singlequotedString - - begin - ' - beginCaptures - - 0 - - name - punctuation.definition.string.begin.xml - - - end - ' - endCaptures - - 0 - - name - punctuation.definition.string.end.xml - - - name - string.quoted.single.xml - patterns - - - include - #xml-entity - - - - - scopeName - source.scala - uuid - 158C0929-299A-40C8-8D89-316BE0C446E8 - -