mirror of
https://github.com/godotengine/godot-vscode-plugin.git
synced 2026-01-04 10:09:58 +03:00
Fix bad formatting on several operators (#605)
Many, many formatter and syntax highlighting improvements.
This commit is contained in:
18
package.json
18
package.json
@@ -271,6 +271,24 @@
|
||||
"default": true,
|
||||
"description": "Whether to reveal the terminal when launching the Godot Editor"
|
||||
},
|
||||
"godotTools.formatter.emptyLinesBeforeFunctions": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"one",
|
||||
"two"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"One line before functions. A more compact style.",
|
||||
"Two lines before functions. Conforms to the official GDScript style guide."
|
||||
],
|
||||
"default": "two",
|
||||
"description": "Number of blank lines to leave before functions."
|
||||
},
|
||||
"godotTools.formatter.denseFunctionDeclarations": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Whether extra space should be removed from function declarations"
|
||||
},
|
||||
"godotTools.lsp.serverProtocol": {
|
||||
"type": [
|
||||
"string"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as path from "path";
|
||||
import * as path from "node:path";
|
||||
import * as vscode from "vscode";
|
||||
import { attemptSettingsUpdate, get_extension_uri, clean_godot_path } from "./utils";
|
||||
import {
|
||||
@@ -81,6 +81,10 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
async function initial_setup() {
|
||||
const projectVersion = await get_project_version();
|
||||
if (projectVersion === undefined) {
|
||||
// TODO: actually handle this?
|
||||
return;
|
||||
}
|
||||
const settingName = `editorPath.godot${projectVersion[0]}`;
|
||||
const result = verify_godot_version(get_configuration(settingName), projectVersion[0]);
|
||||
const godotPath = result.godotPath;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as vscode from "vscode";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import * as path from "node:path";
|
||||
import * as fs from "node:fs";
|
||||
|
||||
import { format_document } from "./textmate";
|
||||
|
||||
|
||||
0
src/formatter/snapshot_template/in.gd
Normal file
0
src/formatter/snapshot_template/in.gd
Normal file
0
src/formatter/snapshot_template/out.gd
Normal file
0
src/formatter/snapshot_template/out.gd
Normal file
@@ -26,6 +26,9 @@ func f():
|
||||
a= 1.0* .2
|
||||
a =1.0 * 2.
|
||||
|
||||
a = 10**10
|
||||
a = min(10, 10**10)
|
||||
|
||||
a= a% b
|
||||
a =1%2
|
||||
|
||||
@@ -36,3 +39,16 @@ func f():
|
||||
|
||||
var v = Vector2( 1 , - 1 )
|
||||
var w = Vector2(1,10-1)
|
||||
|
||||
print( - 1 )
|
||||
print( 1 - 1 )
|
||||
|
||||
print( - 1 + (1-1))
|
||||
print( - 1 + (-1-1))
|
||||
|
||||
if a > - 1:
|
||||
if a < - 1:
|
||||
if a == - 1:
|
||||
pass
|
||||
|
||||
return - 1
|
||||
|
||||
@@ -26,6 +26,9 @@ func f():
|
||||
a = 1.0 * .2
|
||||
a = 1.0 * 2.
|
||||
|
||||
a = 10 ** 10
|
||||
a = min(10, 10 ** 10)
|
||||
|
||||
a = a % b
|
||||
a = 1 % 2
|
||||
|
||||
@@ -36,3 +39,16 @@ func f():
|
||||
|
||||
var v = Vector2(1, -1)
|
||||
var w = Vector2(1, 10 - 1)
|
||||
|
||||
print(-1)
|
||||
print(1 - 1)
|
||||
|
||||
print(-1 + (1 - 1))
|
||||
print(-1 + (-1 - 1))
|
||||
|
||||
if a > -1:
|
||||
if a < -1:
|
||||
if a == -1:
|
||||
pass
|
||||
|
||||
return -1
|
||||
|
||||
15
src/formatter/snapshots/assignment-operators/in.gd
Normal file
15
src/formatter/snapshots/assignment-operators/in.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
func f():
|
||||
# arithmetic
|
||||
x += 1
|
||||
x -= 1
|
||||
x *= 1
|
||||
x /= 1
|
||||
x %= 1
|
||||
|
||||
# bitwise
|
||||
x |= 1
|
||||
x &= 1
|
||||
x ~= 1
|
||||
x /= 1
|
||||
x >>= 1
|
||||
x <<= 1
|
||||
15
src/formatter/snapshots/assignment-operators/out.gd
Normal file
15
src/formatter/snapshots/assignment-operators/out.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
func f():
|
||||
# arithmetic
|
||||
x += 1
|
||||
x -= 1
|
||||
x *= 1
|
||||
x /= 1
|
||||
x %= 1
|
||||
|
||||
# bitwise
|
||||
x |= 1
|
||||
x &= 1
|
||||
x ~= 1
|
||||
x /= 1
|
||||
x >>= 1
|
||||
x <<= 1
|
||||
5
src/formatter/snapshots/bitwise-operators/in.gd
Normal file
5
src/formatter/snapshots/bitwise-operators/in.gd
Normal file
@@ -0,0 +1,5 @@
|
||||
func f():
|
||||
collision_mask = 1 << 1 | 1 << 3
|
||||
collision_mask = 1 << 1 & 1 << 3
|
||||
collision_mask = ~1
|
||||
collision_mask = 1 ^ ~ 1
|
||||
5
src/formatter/snapshots/bitwise-operators/out.gd
Normal file
5
src/formatter/snapshots/bitwise-operators/out.gd
Normal file
@@ -0,0 +1,5 @@
|
||||
func f():
|
||||
collision_mask = 1 << 1 | 1 << 3
|
||||
collision_mask = 1 << 1 & 1 << 3
|
||||
collision_mask = ~1
|
||||
collision_mask = 1 ^ ~1
|
||||
@@ -8,3 +8,7 @@ func f():
|
||||
func g():
|
||||
print(true and ( not false ) or ( true))
|
||||
print(true and not false or not (true) )
|
||||
|
||||
func h():
|
||||
print(true && ( not false ) || ( true))
|
||||
print(true && not false || not (true) )
|
||||
|
||||
@@ -8,3 +8,7 @@ func f():
|
||||
func g():
|
||||
print(true and (not false) or (true))
|
||||
print(true and not false or not (true))
|
||||
|
||||
func h():
|
||||
print(true && (not false) || (true))
|
||||
print(true && not false || not (true))
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
|
||||
|
||||
|
||||
class Test:
|
||||
|
||||
|
||||
|
||||
|
||||
func _ready():
|
||||
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
func test():
|
||||
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
# comments
|
||||
func with_comments():
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
class Test:
|
||||
|
||||
|
||||
func _ready():
|
||||
|
||||
pass
|
||||
|
||||
|
||||
func test():
|
||||
|
||||
pass
|
||||
|
||||
|
||||
# comments
|
||||
func with_comments():
|
||||
|
||||
pass
|
||||
|
||||
@@ -2,14 +2,14 @@ var a = 10
|
||||
var b := 10
|
||||
var c: int = 10
|
||||
|
||||
func f(b:=10):
|
||||
return func(c:=10):
|
||||
func f(b := 10):
|
||||
return func(c := 10):
|
||||
pass
|
||||
|
||||
func f(b: int=10):
|
||||
return func(c: int=10):
|
||||
func f(b: int = 10):
|
||||
return func(c: int = 10):
|
||||
pass
|
||||
|
||||
func f(b=10):
|
||||
return func(c=10):
|
||||
func f(b = 10):
|
||||
return func(c = 10):
|
||||
pass
|
||||
|
||||
10
src/formatter/snapshots/keywords/in.gd
Normal file
10
src/formatter/snapshots/keywords/in.gd
Normal file
@@ -0,0 +1,10 @@
|
||||
func f():
|
||||
const a = preload("res://a.gd")
|
||||
const b = load("res://b.gd")
|
||||
|
||||
var origin: Vector2 = Vector2.ZERO
|
||||
origin.x = 1
|
||||
var andigin: Vector2 = Vector2.ZERO
|
||||
andigin.x = 1
|
||||
|
||||
print(a)
|
||||
10
src/formatter/snapshots/keywords/out.gd
Normal file
10
src/formatter/snapshots/keywords/out.gd
Normal file
@@ -0,0 +1,10 @@
|
||||
func f():
|
||||
const a = preload("res://a.gd")
|
||||
const b = load("res://b.gd")
|
||||
|
||||
var origin: Vector2 = Vector2.ZERO
|
||||
origin.x = 1
|
||||
var andigin: Vector2 = Vector2.ZERO
|
||||
andigin.x = 1
|
||||
|
||||
print(a)
|
||||
4
src/formatter/snapshots/match/in.gd
Normal file
4
src/formatter/snapshots/match/in.gd
Normal file
@@ -0,0 +1,4 @@
|
||||
func f(x):
|
||||
match x:
|
||||
var y when y>20:
|
||||
pass
|
||||
4
src/formatter/snapshots/match/out.gd
Normal file
4
src/formatter/snapshots/match/out.gd
Normal file
@@ -0,0 +1,4 @@
|
||||
func f(x):
|
||||
match x:
|
||||
var y when y > 20:
|
||||
pass
|
||||
@@ -69,3 +69,6 @@ var a = $"%Child/GrandChild".some_method()
|
||||
var a = $Child.get_node('GrandChild').some_method()
|
||||
var a = $"Child".get_node('GrandChild').some_method()
|
||||
var a = $"%Child".get_node('GrandChild').some_method()
|
||||
|
||||
func f():
|
||||
$Child.add_child(%Unique)
|
||||
|
||||
@@ -69,3 +69,6 @@ var a = $"%Child/GrandChild".some_method()
|
||||
var a = $Child.get_node('GrandChild').some_method()
|
||||
var a = $"Child".get_node('GrandChild').some_method()
|
||||
var a = $"%Child".get_node('GrandChild').some_method()
|
||||
|
||||
func f():
|
||||
$Child.add_child(%Unique)
|
||||
|
||||
@@ -21,6 +21,7 @@ export const keywords = [
|
||||
"master",
|
||||
"mastersync",
|
||||
"match",
|
||||
"when",
|
||||
"not",
|
||||
"onready",
|
||||
"or",
|
||||
@@ -58,10 +59,14 @@ export const symbols = [
|
||||
"&=",
|
||||
"^=",
|
||||
"|=",
|
||||
"~=",
|
||||
"<<=",
|
||||
">>=",
|
||||
":=",
|
||||
"->",
|
||||
"&",
|
||||
"|",
|
||||
"^",
|
||||
"-",
|
||||
"+",
|
||||
"/",
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Range, TextDocument, TextEdit } from "vscode";
|
||||
import * as fs from "fs";
|
||||
import { Range, type TextDocument, TextEdit, TextLine } from "vscode";
|
||||
import * as fs from "node:fs";
|
||||
import * as vsctm from "vscode-textmate";
|
||||
import * as oniguruma from "vscode-oniguruma";
|
||||
import { keywords, symbols } from "./symbols";
|
||||
import { get_extension_uri, createLogger } from "../utils";
|
||||
import { get_configuration, get_extension_uri, createLogger } from "../utils";
|
||||
|
||||
const log = createLogger("formatter.tm");
|
||||
|
||||
// Promisify readFile
|
||||
function readFile(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readFile(path, (error, data) => error ? reject(error) : resolve(data));
|
||||
fs.readFile(path, (error, data) => (error ? reject(error) : resolve(data)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,17 +22,21 @@ const wasmBin = fs.readFileSync(wasmPath).buffer;
|
||||
const registry = new vsctm.Registry({
|
||||
onigLib: oniguruma.loadWASM(wasmBin).then(() => {
|
||||
return {
|
||||
createOnigScanner(patterns) { return new oniguruma.OnigScanner(patterns); },
|
||||
createOnigString(s) { return new oniguruma.OnigString(s); }
|
||||
createOnigScanner(patterns) {
|
||||
return new oniguruma.OnigScanner(patterns);
|
||||
},
|
||||
createOnigString(s) {
|
||||
return new oniguruma.OnigString(s);
|
||||
},
|
||||
};
|
||||
}),
|
||||
loadGrammar: (scopeName) => {
|
||||
if (scopeName === "source.gdscript") {
|
||||
return readFile(grammarPath).then(data => vsctm.parseRawGrammar(data.toString(), grammarPath));
|
||||
return readFile(grammarPath).then((data) => vsctm.parseRawGrammar(data.toString(), grammarPath));
|
||||
}
|
||||
// console.log(`Unknown scope name: ${scopeName}`);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
interface Token {
|
||||
@@ -47,6 +51,16 @@ interface Token {
|
||||
skip?: boolean;
|
||||
}
|
||||
|
||||
class FormatterOptions {
|
||||
emptyLinesBeforeFunctions: "one" | "two";
|
||||
denseFunctionDeclarations: boolean;
|
||||
|
||||
constructor() {
|
||||
this.emptyLinesBeforeFunctions = get_configuration("formatter.emptyLinesBeforeFunctions");
|
||||
this.denseFunctionDeclarations = get_configuration("formatter.denseFunctionDeclarations");
|
||||
}
|
||||
}
|
||||
|
||||
function parse_token(token: Token) {
|
||||
if (token.scopes.includes("string.quoted.gdscript")) {
|
||||
token.string = true;
|
||||
@@ -65,6 +79,10 @@ function parse_token(token: Token) {
|
||||
token.type = "symbol";
|
||||
return;
|
||||
}
|
||||
// "preload" is highlighted as a keyword but it behaves like a function
|
||||
if (token.value === "preload") {
|
||||
return;
|
||||
}
|
||||
if (token.scopes.includes("keyword.language.gdscript")) {
|
||||
token.type = "keyword";
|
||||
return;
|
||||
@@ -79,7 +97,7 @@ function parse_token(token: Token) {
|
||||
}
|
||||
}
|
||||
|
||||
function between(tokens: Token[], current: number) {
|
||||
function between(tokens: Token[], current: number, options: FormatterOptions) {
|
||||
const nextToken = tokens[current];
|
||||
const prevToken = tokens[current - 1];
|
||||
const next = nextToken.value;
|
||||
@@ -89,26 +107,44 @@ function between(tokens: Token[], current: number) {
|
||||
|
||||
if (!prev) return "";
|
||||
|
||||
if (next === "##") return " ";
|
||||
if (next === "#") return " ";
|
||||
if (prevToken.skip && nextToken.skip) return "";
|
||||
|
||||
if (prev === "(") return "";
|
||||
|
||||
if (nextToken.param) {
|
||||
if (prev === "-" && tokens[current - 2]?.value === ",") {
|
||||
return "";
|
||||
if (options.denseFunctionDeclarations) {
|
||||
if (prev === "-") {
|
||||
if (tokens[current - 2]?.value === "=") return "";
|
||||
if (["keyword", "symbol"].includes(tokens[current - 2].type)) {
|
||||
return "";
|
||||
}
|
||||
if ([",", "("].includes(tokens[current - 2]?.value)) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (next === "%") return " ";
|
||||
if (prev === "%") return " ";
|
||||
if (next === "=") {
|
||||
if (tokens[current - 2]?.value === ":") return " ";
|
||||
return "";
|
||||
}
|
||||
if (prev === "=") {
|
||||
if (tokens[current - 3]?.value === ":") return " ";
|
||||
return "";
|
||||
}
|
||||
if (prevToken?.type === "symbol") return " ";
|
||||
if (nextToken.type === "symbol") return " ";
|
||||
} else {
|
||||
if (next === ":") {
|
||||
if (tokens[current + 1]?.value === "=") return " ";
|
||||
}
|
||||
}
|
||||
if (next === "%") return " ";
|
||||
if (prev === "%") return " ";
|
||||
if (next === "=") return "";
|
||||
if (prev === "=") return "";
|
||||
if (next === ":=") return "";
|
||||
if (prev === ":=") return "";
|
||||
if (prevToken?.type === "symbol") return " ";
|
||||
if (nextToken.type === "symbol") return " ";
|
||||
}
|
||||
|
||||
if (next === ":") {
|
||||
if (["var", "const"].includes(tokens[current - 2]?.value)) {
|
||||
if (tokens[current + 1]?.value !== "=") return "";
|
||||
if (tokens[current + 1]?.value !== "=") return "";
|
||||
return " ";
|
||||
}
|
||||
@@ -117,7 +153,10 @@ function between(tokens: Token[], current: number) {
|
||||
if (prev === "@") return "";
|
||||
|
||||
if (prev === "-") {
|
||||
if (tokens[current - 2]?.value === "(") {
|
||||
if (["keyword", "symbol"].includes(tokens[current - 2].type)) {
|
||||
return "";
|
||||
}
|
||||
if ([",", "(", "["].includes(tokens[current - 2]?.value)) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -134,6 +173,7 @@ function between(tokens: Token[], current: number) {
|
||||
if (prev === "[" && nextToken.type === "symbol") return "";
|
||||
if (prev === ":") return " ";
|
||||
if (prev === ";") return " ";
|
||||
if (prev === "##") return " ";
|
||||
if (prev === "#") return " ";
|
||||
if (next === "=") return " ";
|
||||
if (prev === "=") return " ";
|
||||
@@ -157,7 +197,13 @@ function between(tokens: Token[], current: number) {
|
||||
|
||||
let grammar = null;
|
||||
|
||||
registry.loadGrammar("source.gdscript").then(g => { grammar = g; });
|
||||
registry.loadGrammar("source.gdscript").then((g) => {
|
||||
grammar = g;
|
||||
});
|
||||
|
||||
function is_comment(line: TextLine): boolean {
|
||||
return line.text[line.firstNonWhitespaceCharacterIndex] === "#";
|
||||
}
|
||||
|
||||
export function format_document(document: TextDocument): TextEdit[] {
|
||||
// quit early if grammar is not loaded
|
||||
@@ -166,35 +212,67 @@ export function format_document(document: TextDocument): TextEdit[] {
|
||||
}
|
||||
const edits: TextEdit[] = [];
|
||||
|
||||
const options = new FormatterOptions();
|
||||
|
||||
let lineTokens: vsctm.ITokenizeLineResult = null;
|
||||
let onlyEmptyLinesSoFar = true;
|
||||
let emptyLineCount = 0;
|
||||
let firstEmptyLine = 0;
|
||||
for (let lineNum = 0; lineNum < document.lineCount; lineNum++) {
|
||||
const line = document.lineAt(lineNum);
|
||||
|
||||
// skip empty lines
|
||||
if (line.isEmptyOrWhitespace) {
|
||||
if (line.isEmptyOrWhitespace || is_comment(line)) {
|
||||
// delete empty lines at the beginning of the file
|
||||
if (onlyEmptyLinesSoFar) {
|
||||
edits.push(TextEdit.delete(line.rangeIncludingLineBreak));
|
||||
} else {
|
||||
// Limit the number of consecutive empty lines
|
||||
const maxEmptyLines: number = 1;
|
||||
if (maxEmptyLines === 1) {
|
||||
if (lineNum < document.lineCount - 1 && document.lineAt(lineNum + 1).isEmptyOrWhitespace) {
|
||||
edits.push(TextEdit.delete(line.rangeIncludingLineBreak));
|
||||
}
|
||||
} else if (maxEmptyLines === 2) {
|
||||
if (lineNum < document.lineCount - 2 && document.lineAt(lineNum + 1).isEmptyOrWhitespace && document.lineAt(lineNum + 2).isEmptyOrWhitespace) {
|
||||
edits.push(TextEdit.delete(line.rangeIncludingLineBreak));
|
||||
}
|
||||
if (emptyLineCount === 0) {
|
||||
firstEmptyLine = lineNum;
|
||||
}
|
||||
if (!is_comment(line)) {
|
||||
emptyLineCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// delete empty lines at the end of the file
|
||||
if (lineNum === document.lineCount - 1) {
|
||||
for (let i = lineNum - emptyLineCount + 1; i < document.lineCount; i++) {
|
||||
edits.push(TextEdit.delete(document.lineAt(i).rangeIncludingLineBreak));
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
onlyEmptyLinesSoFar = false;
|
||||
|
||||
// delete consecutive empty lines
|
||||
if (emptyLineCount) {
|
||||
let maxEmptyLines = 1;
|
||||
|
||||
const start = line.text.trimStart();
|
||||
if (options.emptyLinesBeforeFunctions === "two") {
|
||||
if (start.startsWith("func") || start.startsWith("static func")) {
|
||||
maxEmptyLines++;
|
||||
}
|
||||
}
|
||||
if (start.startsWith("class")) {
|
||||
maxEmptyLines++;
|
||||
}
|
||||
let i = 0;
|
||||
let deletedLines = 0;
|
||||
const linesToDelete = emptyLineCount - maxEmptyLines;
|
||||
while (i < lineNum && deletedLines < linesToDelete) {
|
||||
const candidate = document.lineAt(firstEmptyLine + i++);
|
||||
if (candidate.isEmptyOrWhitespace) {
|
||||
edits.push(TextEdit.delete(candidate.rangeIncludingLineBreak));
|
||||
deletedLines++;
|
||||
}
|
||||
}
|
||||
emptyLineCount = 0;
|
||||
}
|
||||
|
||||
// skip comments
|
||||
if (line.text[line.firstNonWhitespaceCharacterIndex] === "#") {
|
||||
if (is_comment(line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -228,7 +306,7 @@ export function format_document(document: TextDocument): TextEdit[] {
|
||||
if (i > 0 && tokens[i - 1].string === true && tokens[i].string === true) {
|
||||
nextLine += tokens[i].original;
|
||||
} else {
|
||||
nextLine += between(tokens, i) + tokens[i].value.trim();
|
||||
nextLine += between(tokens, i, options) + tokens[i].value.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as vscode from "vscode";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import { execSync } from "child_process";
|
||||
import * as path from "node:path";
|
||||
import * as fs from "node:fs";
|
||||
import * as os from "node:os";
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
let projectDir: string | undefined = undefined;
|
||||
let projectFile: string | undefined = undefined;
|
||||
|
||||
@@ -55,11 +55,10 @@
|
||||
{ "include": "#nodepath_object" },
|
||||
{ "include": "#nodepath_function" },
|
||||
{ "include": "#strings" },
|
||||
{ "include": "#builtin_classes" },
|
||||
{ "include": "#const_vars" },
|
||||
{ "include": "#keywords" },
|
||||
{ "include": "#logic_operator" },
|
||||
{ "include": "#compare_operator" },
|
||||
{ "include": "#arithmetic_operator" },
|
||||
{ "include": "#operators" },
|
||||
{ "include": "#lambda_declaration" },
|
||||
{ "include": "#class_declaration" },
|
||||
{ "include": "#variable_declaration" },
|
||||
@@ -77,13 +76,12 @@
|
||||
{ "include": "#func" },
|
||||
{ "include": "#letter" },
|
||||
{ "include": "#numbers" },
|
||||
{ "include": "#builtin_classes" },
|
||||
{ "include": "#pascal_case_class" },
|
||||
{ "include": "#line_continuation" }
|
||||
]
|
||||
},
|
||||
"comment": {
|
||||
"match": "(#).*$\\n?",
|
||||
"match": "(##|#).*$\\n?",
|
||||
"name": "comment.line.number-sign.gdscript",
|
||||
"captures": { "1": { "name": "punctuation.definition.comment.number-sign.gdscript" } }
|
||||
},
|
||||
@@ -97,14 +95,37 @@
|
||||
"name": "constant.character.escape.gdscript",
|
||||
"match": "\\\\."
|
||||
},
|
||||
{ "include": "#string_formatting" }
|
||||
{ "include": "#string_percent_placeholders" },
|
||||
{ "include": "#string_bracket_placeholders" }
|
||||
]
|
||||
},
|
||||
"string_formatting": {
|
||||
"string_percent_placeholders": {
|
||||
"name": "meta.format.percent.gdscript",
|
||||
"match": "(?x)\n (\n % (\\([\\w\\s]*\\))?\n [-+#0 ]*\n (\\d+|\\*)? (\\.(\\d+|\\*))?\n ([hlL])?\n [diouxXeEfFgGcrsab%]\n )\n",
|
||||
"captures": { "1": { "name": "constant.character.format.placeholder.other.gdscript" } }
|
||||
},
|
||||
"string_bracket_placeholders": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "meta.format.brace.gdscript",
|
||||
"match": "(?x)\n (\n {{ | }}\n | (?:\n {\n \\w* (\\.[[:alpha:]_]\\w* | \\[[^\\]'\"]+\\])*\n (![rsa])?\n ( : \\w? [<>=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?\n })\n )\n",
|
||||
"captures": {
|
||||
"1": { "name": "constant.character.format.placeholder.other.gdscript" },
|
||||
"3": { "name": "storage.type.format.gdscript" },
|
||||
"4": { "name": "storage.type.format.gdscript" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "meta.format.brace.gdscript",
|
||||
"match": "(?x)\n (\n {\n \\w* (\\.[[:alpha:]_]\\w* | \\[[^\\]'\"]+\\])*\n (![rsa])?\n (:)\n [^'\"{}\\n]* (?:\n \\{ [^'\"}\\n]*? \\} [^'\"{}\\n]*\n )*\n }\n )\n",
|
||||
"captures": {
|
||||
"1": { "name": "constant.character.format.placeholder.other.gdscript" },
|
||||
"3": { "name": "storage.type.format.gdscript" },
|
||||
"4": { "name": "storage.type.format.gdscript" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"nodepath_object": {
|
||||
"name": "meta.literal.nodepath.gdscript",
|
||||
"begin": "(NodePath)\\s*(?:\\()",
|
||||
@@ -154,10 +175,6 @@
|
||||
"match": "\\bfunc\\b",
|
||||
"name": "keyword.language.gdscript"
|
||||
},
|
||||
"logic_operator": {
|
||||
"match": "\\b(and|or|not|!)\\b",
|
||||
"name": "keyword.operator.wordlike.gdscript"
|
||||
},
|
||||
"in_keyword": {
|
||||
"patterns": [
|
||||
{
|
||||
@@ -180,12 +197,33 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"operators": {
|
||||
"patterns": [
|
||||
{ "include": "#wordlike_operator" },
|
||||
{ "include": "#boolean_operator" },
|
||||
{ "include": "#arithmetic_operator" },
|
||||
{ "include": "#bitwise_operator" },
|
||||
{ "include": "#compare_operator" }
|
||||
]
|
||||
},
|
||||
"wordlike_operator": {
|
||||
"match": "\\b(and|or|not)\\b",
|
||||
"name": "keyword.operator.wordlike.gdscript"
|
||||
},
|
||||
"boolean_operator": {
|
||||
"match": "(&&|\\|\\|)",
|
||||
"name": "keyword.operator.boolean.gdscript"
|
||||
},
|
||||
"bitwise_operator": {
|
||||
"match": "&|\\||<<=|>>=|<<|>>|\\^|~",
|
||||
"name": "keyword.operator.bitwise.gdscript"
|
||||
},
|
||||
"compare_operator": {
|
||||
"match": "<=|>=|==|<|>|!=",
|
||||
"match": "<=|>=|==|<|>|!=|!",
|
||||
"name": "keyword.operator.comparison.gdscript"
|
||||
},
|
||||
"arithmetic_operator": {
|
||||
"match": "->|\\+=|-=|\\*=|/=|%=|&=|\\|=|\\*|/|%|\\+|-|<<|>>|&|\\||\\^|~|!",
|
||||
"match": "->|\\+=|-=|\\*=|\\^=|/=|%=|&=|~=|\\|=|\\*\\*|\\*|/|%|\\+|-",
|
||||
"name": "keyword.operator.arithmetic.gdscript"
|
||||
},
|
||||
"assignment_operator": {
|
||||
@@ -193,11 +231,11 @@
|
||||
"name": "keyword.operator.assignment.gdscript"
|
||||
},
|
||||
"control_flow": {
|
||||
"match": "\\b(?:if|elif|else|while|break|continue|pass|return|match|yield|await)\\b",
|
||||
"match": "\\b(?:if|elif|else|while|break|continue|pass|return|match|when|yield|await)\\b",
|
||||
"name": "keyword.control.gdscript"
|
||||
},
|
||||
"keywords": {
|
||||
"match": "\\b(?:class|class_name|is|onready|tool|static|export|as|void|enum|preload|assert|breakpoint|rpc|sync|remote|master|puppet|slave|remotesync|mastersync|puppetsync|trait|namespace)\\b",
|
||||
"match": "\\b(?:class|class_name|is|onready|tool|static|export|as|void|enum|preload|assert|breakpoint|sync|remote|master|puppet|slave|remotesync|mastersync|puppetsync|trait|namespace)\\b",
|
||||
"name": "keyword.language.gdscript"
|
||||
},
|
||||
"letter": {
|
||||
@@ -397,7 +435,7 @@
|
||||
"name": "constant.language.gdscript"
|
||||
},
|
||||
"pascal_case_class": {
|
||||
"match": "\\b([A-Z][a-z_0-9]*([A-Z]?[a-z_0-9]+)*[A-Z]?)\\b",
|
||||
"match": "\\b([A-Z]+[a-z_0-9]*([A-Z]?[a-z_0-9]+)*[A-Z]?)\\b",
|
||||
"name": "entity.name.type.class.gdscript"
|
||||
},
|
||||
"signal_declaration_bare": {
|
||||
@@ -494,7 +532,7 @@
|
||||
"beginCaptures": {
|
||||
"1": { "name": "variable.parameter.function.language.gdscript" },
|
||||
"2": { "name": "punctuation.separator.annotation.gdscript" },
|
||||
"3": { "name": "entity.name.type.class.builtin.gdscript" }
|
||||
"3": { "name": "entity.name.type.class.gdscript" }
|
||||
},
|
||||
"end": "(,)|(?=\\))",
|
||||
"endCaptures": { "1": { "name": "punctuation.separator.parameters.gdscript" } },
|
||||
|
||||
Reference in New Issue
Block a user