Compare commits

..

34 Commits

Author SHA1 Message Date
Geequlim
2ba776dc40 Merge pull request #94 from anoadragon453/patch-1
Fix small grammar issue
2019-03-13 20:40:28 +08:00
Andrew Morgan
abaa5d32d0 Fix some grammar issue
Lint configuration, not configurations.
2019-03-12 15:24:17 +00:00
Geequlim
06817de78e Merge pull request #84 from lleaff/feat-reuse-term
Close existing terminal when executing "run" commands
2018-12-03 13:06:03 +08:00
lleaff
6aab0be1d4 "run" commands close existing launched instances 2018-10-10 02:03:04 +02:00
Geequlim
307e29a7ec Merge pull request #79 from AlienGamesLLC/master
single line if-else statement
2018-09-08 12:04:47 +08:00
Geequlim
58e8626cac Merge pull request #77 from fractile81/deps-updates
Dependencies all updated to latest versions.
2018-09-08 11:55:57 +08:00
Geequlim
3ac359af86 Merge branch 'master' into deps-updates 2018-09-08 11:55:40 +08:00
Akira Kido
c20909fdb3 fixed regex to reflect my issue 2018-09-04 17:30:40 +09:00
Geequlim
ec9fe7fdc1 Merge pull request #80 from fractile81/update-readme
Further README refinements.  Updates to strings for consistency.
2018-09-04 09:20:58 +08:00
Craig A. Hancock
c84d7f9c12 Further README refinements. Updates to strings in package.json and tool_manager.ts to match. 2018-09-03 10:26:22 -06:00
Akira Kido
492fe5663c single if-else statement 2018-09-03 18:58:47 +09:00
Geequlim
8f5da41a41 Merge pull request #78 from fractile81/update-readme
README updated for consistency.
2018-09-03 00:12:39 +08:00
Craig A. Hancock
e4d86f35be README updated for consistency. 2018-09-02 07:37:37 -06:00
Craig A. Hancock
eed2d4f516 Dependencies all updated to latest versions. Only affects development packages. 2018-09-02 07:07:31 -06:00
geequlim
63b10b1d72 Sync docs with godot 3.0.4
Release 0.3.7
2018-06-29 14:03:42 +08:00
geequlim
fdc07e4743 fix syntax checing with inline condition expression fix #58 2018-06-29 13:19:14 +08:00
geequlim
80ce466d53 fix #54 2018-06-29 13:09:49 +08:00
geequlim
7e3e95086b Enable/Disable unused symbol checking 2018-06-29 13:04:25 +08:00
geequlim
7c8696abc1 Fix bracket checing in conditions fix #59 2018-06-29 12:53:32 +08:00
geequlim
8ddc7dd310 Indentifier checking for keywords bug fix
fix #65
2018-06-29 12:47:11 +08:00
geequlim
e76c06a31a Don't compains with assert checking fix #66 2018-06-29 12:35:10 +08:00
geequlim
4c0f864cf8 Add lint configuration to enable or disable some feature for syntax check 2018-06-29 12:20:09 +08:00
Geequlim
462a7bdbd7 Merge pull request #56 from RivenCode/master
Added handling of paths with spaces in them
2018-03-18 19:48:33 +08:00
RivenCode
e2dbf8146f Added handling of paths with spaces in them.
For the editor path, we use PowerShell syntax, when required.
2018-03-18 21:14:14 +11:00
geequlim
7b21267d07 Update to 0.3.6 2018-02-01 23:06:28 +08:00
geequlim
ef3a70f417 Set default project file to project.godot 2018-02-01 22:52:22 +08:00
geequlim
fc027ea9ad Update to 0.3.5 to works fine with Godot 3.0 2018-01-30 22:47:57 +08:00
geequlim
4c47fff9af Add option to disable syntax checking for GDScript 2018-01-01 15:22:29 +08:00
geequlim
d7ff45edac Add more text resource type support with syntax highlight. 2017-12-25 21:28:43 +08:00
Geequlim
38b0898649 Fix syntax checking for inline if else statement 2017-12-22 15:23:10 +08:00
geequlim
a3b062e242 Release 0.3.4 2017-10-28 11:53:27 +08:00
Geequlim
071e59364f Show window progress when parse workspace symbols 2017-10-16 15:33:25 +08:00
Geequlim
a47980981b Show relative script path in code completion and hover documentation 2017-10-16 15:00:47 +08:00
Geequlim
edcb8b96d1 Fix builtin documentation parsing for godot 2.1 fix #44 2017-10-16 14:17:43 +08:00
12 changed files with 84196 additions and 98153 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ test
*.vsix *.vsix
configurations/tmp.txt configurations/tmp.txt
configurations/test.py configurations/test.py
.vscode-test

View File

@@ -1,5 +1,35 @@
# Change Log # Change Log
### 0.3.7
* Add `lint` configuration to control the behaviors of syntax checking
* Fix error with run godot editor when the editor contains spaces
* Disable semicolons and brackets checks as default can be enabled with project settings
* Fix bugs in syntax valiadating
* Sync documentations with godot 3.0.4
```json
{
"lint": {
"semicolon": true,
"conditionBrackets": true
}
}
```
### 0.3.6
* Fix project configuartion file path
### 0.3.5
* Add option to disable syntax checking for GDScript
* Improved inline if else statement syntax checking
* More resource type supported for syntax highglight
* Bump default godot version to 3.0
* Sync the documentations from godot 3.0
### 0.3.4
* Fix bug with builtin symbols parsing for godot 2.1
* Improved hover documentation
* Show window progress when parsing workspace symbols
### 0.3.3 ### 0.3.3
* Fix some syntax checking errors. * Fix some syntax checking errors.
* Fix problems with hover documentation with latest VSCode. * Fix problems with hover documentation with latest VSCode.

View File

@@ -2,77 +2,63 @@ A complete set of tools to code games with the [Godot game engine](http://www.go
## Features ## Features
The plug-in comes with a wealth of features to make your programming experience as comfortable as possible The extension comes with a wealth of features to make your Godot programming experience as comfortable as possible:
- Syntax highlighting for the GDscript language - Syntax highlighting for the GDscript (`.gd`) language
- Syntax highlighting for the tscn and tres scene formats - Syntax highlighting for the `.tscn` and `.tres` scene formats
- Function definitions and documentation on hover - Function definitions and documentation display on hover (see image below)
- Rich auto completion - Rich auto-completion
- Static code validation - Static code validation
- Open projects and scenes in Godot from VScode - Open projects and scenes in Godot from VS Code
- Ctrl click on a variable or method call to jump to its definition - Ctrl-click on a variable or method call to jump to its definition
- Full documentation supported with API of godot engine - Full documentation of the Godot engine's API supported
![Showing the documentation on hover feature](img/godot-tools.jpg) ![Showing the documentation on hover feature](img/godot-tools.jpg)
## Available commands ## Available Commands
The plug-ins adds a few entries to the command palette The extension adds a few entries to the VS Code Command Palette under "GodotTools":
- Update Workspace Symbols - Update workspace symbols
- Run workspace as godot project - Run workspace as Godot project
- Open workspace with godot editor - Open workspace with Godot editor
- Run current scene - Run current scene
## Settings ## Settings
If you like this plugin you can set VSCode as your default script editor with following steps: ### Godot
If you like this extension, you can set VS Code as your default script editor for Godot by following these steps:
1. Open editor settings 1. Open editor settings
2. Select `Text Editor / External` 2. Select `Text Editor / External`
3. Check the `Use External Editor` box with mouse click 3. Make sure the `Use External Editor` box is checked
4. Fill `Exec Path` to the path of your Visual Studio Code 4. Fill `Exec Path` with the path to your VS Code executable
5. Fill `Exec Flags` with `{project} --goto {file}:{line}:{col}` 5. Fill `Exec Flags` with `{project} --goto {file}:{line}:{col}`
You can use the following settings to setup the Godot Tools: ### VS Code
- GodotTools.godotVersion: The godot version of your project
- GodotTools.editorPath: An absolute path pointing at the Godot Editor executable file. Required to run the project and test scenes from VScode
- GodotTools.workspaceDocumentWithMarkdown: Control the documentations of workspace symbols should be rendered as plain text or html from markdown
- GodotTools.ignoreIndentedVars: Parse variables defined after indent of not
- GodotTools.parseTextScene: Parse scene files with extension ends with tscn
- GodotTools.completeNodePath: Show node paths of of workspace in the code completion
- GodotTools.godotProjectRoot: The godot project directory wich contains project.godot or engine.cfg
## Issues and contributions
The [Godot Tools](https://github.com/GodotExplorer/godot-tools) and the go to [engine modules](https://github.com/GodotExplorer/editor-server) are all hosted on GitHub. Feel free to open issues there and create pull requests anytime. You can use the following settings to configure Godot Tools:
- **GodotTools.godotVersion** - The Godot version of your project.
- **GodotTools.editorPath** - The absolute path to the Godot executable. Required to run the project and test scenes directly from VS Code.
- **GodotTools.workspaceDocumentWithMarkdown** - Control how the documentation of workspace symbols should be rendered: as plain text or as HTML from Markdown.
- **GodotTools.ignoreIndentedVars** - Only parse variables defined on lines without an indentation.
- **GodotTools.parseTextScene** - Parse a file as a Godot scene when the file name ends with `.tscn`.
- **GodotTools.completeNodePath** - Show node paths within a workspace as part of code completion.
- **GodotTools.godotProjectRoot** - Your Godot project's directory, which contains `project.godot` or `engine.cfg`.
## Issues and Contributions
The [Godot Tools](https://github.com/GodotExplorer/godot-tools) extension and [engine modules](https://github.com/GodotExplorer/editor-server) are both hosted on GitHub. Feel free to open issues there and create pull requests anytime.
See the [full changelog](https://github.com/GodotExplorer/godot-tools/blob/master/CHANGELOG.md) for the latest changes.
## FAQ ## FAQ
### Intelisense isn't showing up for me ### Why isn't Intellisense showing up for me?
Make sure you save your .gd file, then run "GodotTools: Update Workspace Symbols" from the command palate Make sure you save your `.gd` file, then run "GodotTools: Update Workspace Symbols" from the Command Palette.
## Release Notes ## TODO:
* Convert official BBCode documentation into Markdown and render it into HTML with documentation previewer pages
### 0.3.3
* Fix some syntax checking errors.
* Fix problems with hover documentation with latest VSCode.
* Improved builtin class documentation page.
* Update the documentation data with latest godot version.
### 0.3.2
* Fix syntax checking error with match statement.
* Improved documentation for builtin code blocks.
* Start using MarkdonwString to keep links valid.
### 0.3.1
* Update documentations with latest godot.
* Fix errors with run script and run project.
* Improve code completion with opening script file and constants.
* Some improvements for documentations.
[Full change log](https://github.com/GodotExplorer/godot-tools/blob/master/CHANGELOG.md)
## TODOS:
* Convert official BBCode documentation into Markdown and render it to HTML with documentation previewer pages
* Add mermaid support with documentation * Add mermaid support with documentation
* Undefined variable checking * Undefined variable checking

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,15 @@ import xml.etree.ElementTree as ET
import json import json
import os import os
def glob_path(path, pattern):
import os, fnmatch
result = []
for root, _, files in os.walk(path):
for filename in files:
if fnmatch.fnmatch(filename, pattern):
result.append(os.path.join(root, filename))
return result
def parseClass(data): def parseClass(data):
dictCls = dict(data.attrib) dictCls = dict(data.attrib)
dictCls['brief_description'] = data.find("brief_description").text.strip() dictCls['brief_description'] = data.find("brief_description").text.strip()
@@ -56,13 +65,14 @@ def main():
if len(sys.argv) >=2 : if len(sys.argv) >=2 :
if os.path.isdir(sys.argv[1]): if os.path.isdir(sys.argv[1]):
classes = {} classes = {}
for fname in os.listdir(sys.argv[1]): for f in glob_path(sys.argv[1], "**.xml"):
f = os.path.join(sys.argv[1], fname) if f.find("/classes/") == -1 and f.find("/doc_classes/") == -1:
continue
tree = ET.parse(open(f, 'r')) tree = ET.parse(open(f, 'r'))
cls = tree.getroot() cls = tree.getroot()
dictCls = parseClass(cls) dictCls = parseClass(cls)
classes[dictCls['name']] = dictCls classes[dictCls['name']] = dictCls
jsonContent = json.dumps({"classes": classes, "version": "3.0.alpha"}, ensure_ascii=False, indent=2) jsonContent = json.dumps({"classes": classes, "version": "3.0.4"}, ensure_ascii=False, indent=2)
print(jsonContent) print(jsonContent)
if __name__ == '__main__': if __name__ == '__main__':

2235
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,12 +3,12 @@
"displayName": "Godot Tools", "displayName": "Godot Tools",
"icon": "icon.png", "icon": "icon.png",
"description": "Tools for game development with godot game engine", "description": "Tools for game development with godot game engine",
"version": "0.3.3", "version": "0.3.7",
"publisher": "geequlim", "publisher": "geequlim",
"repository": "https://github.com/GodotExplorer/godot-tools", "repository": "https://github.com/GodotExplorer/godot-tools",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"vscode": "^1.16.1" "vscode": "^1.1.21"
}, },
"categories": [ "categories": [
"Other" "Other"
@@ -23,15 +23,15 @@
"commands": [ "commands": [
{ {
"command": "godot.updateWorkspaceSymbols", "command": "godot.updateWorkspaceSymbols",
"title": "GodotTools: Update Workspace Symbols" "title": "GodotTools: Update workspace symbols"
}, },
{ {
"command": "godot.runWorkspace", "command": "godot.runWorkspace",
"title": "GodotTools: Run workspace as godot project" "title": "GodotTools: Run workspace as Godot project"
}, },
{ {
"command": "godot.openWithEditor", "command": "godot.openWithEditor",
"title": "GodotTools: Open workspace with godot editor" "title": "GodotTools: Open workspace with Godot editor"
}, },
{ {
"command": "godot.runCurrentScene", "command": "godot.runCurrentScene",
@@ -40,7 +40,7 @@
], ],
"configuration": { "configuration": {
"type": "object", "type": "object",
"title": "Godot tools configuration", "title": "Godot Tools configuration",
"properties": { "properties": {
"GodotTools.maxNumberOfProblems": { "GodotTools.maxNumberOfProblems": {
"type": "number", "type": "number",
@@ -50,12 +50,12 @@
"GodotTools.editorPath": { "GodotTools.editorPath": {
"type": "string", "type": "string",
"default": "", "default": "",
"description": "The absolute path of your godot editor" "description": "The absolute path to the Godot executable"
}, },
"GodotTools.workspaceDocumentWithMarkdown": { "GodotTools.workspaceDocumentWithMarkdown": {
"type": "boolean", "type": "boolean",
"default": false, "default": false,
"description": "Render workspace documentations as markdown content" "description": "Render workspace documentations as Markdown content"
}, },
"GodotTools.ignoreIndentedVars": { "GodotTools.ignoreIndentedVars": {
"type": "boolean", "type": "boolean",
@@ -64,23 +64,37 @@
}, },
"GodotTools.godotVersion": { "GodotTools.godotVersion": {
"type": "number", "type": "number",
"default": 2.1, "default": 3.0,
"description": "The godot version of your project" "description": "The Godot version of your project"
}, },
"GodotTools.parseTextScene": { "GodotTools.parseTextScene": {
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "Parse scene files with extention ends with tscn" "description": "Parse a file as a Godot scene when the file name ends with tscn"
}, },
"GodotTools.completeNodePath": { "GodotTools.completeNodePath": {
"type": "boolean", "type": "boolean",
"default": false, "default": false,
"description": "Show node pathes of of workspace in the code completion" "description": "Show node paths within a workspace as part of code completion"
}, },
"GodotTools.godotProjectRoot": { "GodotTools.godotProjectRoot": {
"type": "string", "type": "string",
"default": "${workspaceRoot}", "default": "${workspaceRoot}",
"description": "Relate path to the godot project" "description": "Your Godot project's directory"
},
"GodotTools.enableSyntaxChecking": {
"type": "boolean",
"default": true,
"description": "Turn on/off syntax checking for GDScript"
},
"GodotTools.lint": {
"type": "object",
"default": {
"semicolon": false,
"conditionBrackets": false,
"unusedSymbols": true
},
"description": "Lint configuration"
} }
} }
}, },
@@ -99,9 +113,12 @@
{ {
"id": "properties", "id": "properties",
"extensions": [ "extensions": [
".cfg", "cfg",
"tres", "tres",
"tscn" "tscn",
"godot",
"gdns",
"gdnlib"
] ]
} }
], ],
@@ -126,11 +143,11 @@
"test": "node ./node_modules/vscode/bin/test" "test": "node ./node_modules/vscode/bin/test"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^2.0.3", "@types/mocha": "^5.2.5",
"vscode": "^1.1.5", "@types/node": "^10.9.4",
"mocha": "^2.3.3", "mocha": "^5.2.0",
"@types/node": "^6.0.40", "typescript": "^3.0.3",
"@types/mocha": "^2.2.32" "vscode": "^1.1.21"
}, },
"dependencies": { "dependencies": {
"glob": "^7.1.1", "glob": "^7.1.1",

View File

@@ -108,7 +108,7 @@ class Config {
// ---------------------- class ----------------- // ---------------------- class -----------------
const item: CompletionItem = new CompletionItem(classdoc.name, CompletionItemKind.Class); const item: CompletionItem = new CompletionItem(classdoc.name, CompletionItemKind.Class);
item.detail = 'Native Class'; item.detail = 'Native Class';
item.documentation = classdoc.brief_description + " \n\n" +classdoc.description; item.documentation = classdoc.brief_description + " \n" +classdoc.description;
this.builtinCompletions.classes.push(item); this.builtinCompletions.classes.push(item);
builtinSymbolInfoMap[classdoc.name] = {completionItem: item, rowDoc: classdoc}; builtinSymbolInfoMap[classdoc.name] = {completionItem: item, rowDoc: classdoc};
// ----------------------- functions ----------------------- // ----------------------- functions -----------------------
@@ -192,6 +192,11 @@ class Config {
script_files = Object.keys(this.workspaceSymbols); script_files = Object.keys(this.workspaceSymbols);
for (let path of script_files) { for (let path of script_files) {
const script = this.workspaceSymbols[path]; const script = this.workspaceSymbols[path];
if (workspace) {
const root = this.normalizePath(workspace.rootPath) + "/";
if (path.startsWith(root))
path = path.replace(root, "");
}
const addScriptItems = (items, kind: CompletionItemKind, kindName:string = "Symbol", insertText = (n)=>n)=>{ const addScriptItems = (items, kind: CompletionItemKind, kindName:string = "Symbol", insertText = (n)=>n)=>{
const _items: CompletionItem[] = []; const _items: CompletionItem[] = [];
for (let name of Object.keys(items)) { for (let name of Object.keys(items)) {
@@ -203,7 +208,7 @@ class Config {
item.detail = cvalue; item.detail = cvalue;
item.insertText = insertText(name) + (signature=="()"?"()":""); item.insertText = insertText(name) + (signature=="()"?"()":"");
item.documentation = (script.documents && script.documents[name])?script.documents[name]+"\r\n":""; item.documentation = (script.documents && script.documents[name])?script.documents[name]+"\r\n":"";
item.documentation += `${kindName} defined in ${workspace.asRelativePath(path)}`; item.documentation += `${kindName} defined in ${path}`;
_items.push(item); _items.push(item);
} }
return _items; return _items;
@@ -323,4 +328,4 @@ class Config {
}; };
export default new Config(); export default new Config();

View File

@@ -1,189 +1,194 @@
import requestGodot from "../request"; import requestGodot from "../request";
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import {DiagnosticCollection, DiagnosticSeverity} from 'vscode'; import {DiagnosticCollection, DiagnosticSeverity} from 'vscode';
import config from '../config'; import config from '../config';
interface GDParseError { interface GDParseError {
message : string, message : string,
column : number, column : number,
row : number row : number
} }
interface GDScript { interface GDScript {
members : { members : {
constants: {}, constants: {},
functions: {}, functions: {},
variables: {}, variables: {},
signals: {} signals: {}
}, },
base : string, base : string,
errors : GDParseError[], errors : GDParseError[],
valid : boolean, valid : boolean,
is_tool : boolean, is_tool : boolean,
native : string native : string
} }
interface ParseRequest { interface ParseRequest {
text : string, text : string,
path : string path : string
} }
class GDScriptDiagnosticSeverity { class GDScriptDiagnosticSeverity {
private _subscription : DiagnosticCollection; private _subscription : DiagnosticCollection;
constructor() { constructor() {
this._subscription = vscode.languages.createDiagnosticCollection("gdscript") this._subscription = vscode.languages.createDiagnosticCollection("gdscript")
} }
dispose() { dispose() {
this._subscription.dispose() this._subscription.dispose()
} }
async validateScript(doc : vscode.TextDocument, script : any) { async validateScript(doc : vscode.TextDocument, script : any) {
if (doc.languageId == 'gdscript') { if (doc.languageId == 'gdscript') {
if (script) { if (script) {
let diagnostics = [ ...(this.validateExpression(doc)), ...(this.validateUnusedSymbols(doc, script)) ]; let diagnostics = [ ...(this.validateExpression(doc)), ...(this.validateUnusedSymbols(doc, script)) ];
this._subscription.set(doc.uri, diagnostics); this._subscription.set(doc.uri, diagnostics);
return true; return true;
} }
} }
return false; return false;
} }
private validateUnusedSymbols(doc : vscode.TextDocument, script) { private validateUnusedSymbols(doc : vscode.TextDocument, script) {
let diagnostics = []; let diagnostics = [];
const text = doc.getText(); let cfg : any = vscode.workspace.getConfiguration("GodotTools").get("lint");
if (!cfg.unusedSymbols)
const check = (name : string, range : vscode.Range) => { return diagnostics
var matchs = text.match(new RegExp(`([^\\w]|\\[|\\{)\\s*${name}\\s*([^\\w]|\\[|\\{)`, 'g'));
let count = matchs ? matchs.length : 0; const text = doc.getText();
var incomment = text.match(new RegExp(`#.*?([^\\w]|\\[|\\{)\\s*${name}\\s*([^\\w]|\\[|\\{)`, 'g')); const check = (name : string, range : vscode.Range) => {
count -= incomment ? incomment.length : 0; var matchs = text.match(new RegExp(`([^\\w]|\\[|\\{)\\s*${name}\\s*([^\\w]|\\[|\\{)`, 'g'));
if (count <= 1) let count = matchs ? matchs.length : 0;
diagnostics.push(new vscode.Diagnostic(range, `${name} is never used.`, DiagnosticSeverity.Warning)); var incomment = text.match(new RegExp(`#.*?([^\\w]|\\[|\\{)\\s*${name}\\s*([^\\w]|\\[|\\{)`, 'g'));
}; count -= incomment ? incomment.length : 0;
// Unused variables if (count <= 1)
for (let key of Object.keys(script.variables)) diagnostics.push(new vscode.Diagnostic(range, `${name} is never used.`, DiagnosticSeverity.Warning));
check(key, script.variables[key]); };
for (let key of Object.keys(script.constants)) // Unused variables
check(key, script.constants[key]); for (let key of Object.keys(script.variables))
return diagnostics; check(key, script.variables[key]);
} for (let key of Object.keys(script.constants))
check(key, script.constants[key]);
private validateExpression(doc : vscode.TextDocument) { return diagnostics;
let diagnostics = []; }
let expectEndOfLine = false;
const text = doc.getText(); private validateExpression(doc : vscode.TextDocument) {
const lines = text.split(/\r?\n/); let cfg : any = vscode.workspace.getConfiguration("GodotTools").get("lint");
lines.map((line : string, i : number) => {
let matchstart = /[^\s]+.*/.exec(line); let diagnostics = [];
let curLineStartAt = 0; let expectEndOfLine = false;
if (matchstart) const text = doc.getText();
curLineStartAt = matchstart.index; const lines = text.split(/\r?\n/);
lines.map((line : string, i : number) => {
// ignore comments let matchstart = /[^\s]+.*/.exec(line);
if (line.match(/^\s*#.*/) || line.match(/^#.*/)) let curLineStartAt = 0;
return if (matchstart)
// normalize line content curLineStartAt = matchstart.index;
line = "\t" + line + "\t";
var range = new vscode.Range(i, curLineStartAt, i, line.length); // ignore comments
if (line.match(/^\s*#.*/) || line.match(/^#.*/))
if (line.match(/[^#].*?\;/) && !line.match(/[#].*?\;/)) { return
const semicolonIndex = line.indexOf(';'); // normalize line content
diagnostics.push(new vscode.Diagnostic(new vscode.Range(i, semicolonIndex, i, semicolonIndex + 1), "Statement contains a semicolon.", DiagnosticSeverity.Warning)); line = "\t" + line + "\t";
} var range = new vscode.Range(i, curLineStartAt, i, line.length);
if (line.match(/[^#].*?/) && expectEndOfLine) {
if (!line.match(/.*?(\\|\:)/)) { if (cfg.semicolon && line.match(/[^#].*?\;/) && !line.match(/[#].*?\;/)) {
diagnostics.push(new vscode.Diagnostic(range, "': or \\' expected at end of the line.", DiagnosticSeverity.Error)); const semicolonIndex = line.indexOf(';');
expectEndOfLine = false; diagnostics.push(new vscode.Diagnostic(new vscode.Range(i, semicolonIndex, i, semicolonIndex + 1), "Statement contains a semicolon.", DiagnosticSeverity.Warning));
} }
if (line.match(/.*?\:/)) if (line.match(/[^#].*?/) && expectEndOfLine) {
expectEndOfLine = false; if (!line.match(/.*?(\\|\:)/)) {
} diagnostics.push(new vscode.Diagnostic(range, "': or \\' expected at end of the line.", DiagnosticSeverity.Error));
const colonKeywords = /\b(if|elif|else|for|while|func|class|match)\b/; expectEndOfLine = false;
let keywords = line.match(colonKeywords) }
if (keywords) { if (line.match(/.*?\:/))
if(line.match(new RegExp(`".*?\\s${keywords[1]}\\s.*?"`)) || line.match(new RegExp(`'.*?\\s${keywords[1]}\\s.*?\'`))) expectEndOfLine = false;
return }
if(line.match(new RegExp(`.*?#.*?\\s${keywords[1]}\\s.*?`))) const colonKeywords = /\b(if|elif|else|for|while|func|class|match)\b/;
return let keywords = line.match(colonKeywords)
if(line.match(/.*?\sif\s+\w.*?\s+else\s+\w.*/)) if (keywords) {
return if(line.match(new RegExp(`".*?\\s${keywords[1]}\\s.*?"`)) || line.match(new RegExp(`'.*?\\s${keywords[1]}\\s.*?\'`)))
if (line.match(/.*?\\/)) return
expectEndOfLine = true; if(line.match(new RegExp(`.*?#.*?\\s${keywords[1]}\\s.*?`)))
else if (line.match(/.*?\:[\s+]+[^#\s]+/)) return
return if(line.match(/.*?\sif\s+(\!|\[|\{|\w|").*?\s+else\s+[^\s]+/))
else if (!line.match(/.*?(\\|\:)/)) return
diagnostics.push(new vscode.Diagnostic(range, "': or \\' expected at end of the line.", DiagnosticSeverity.Error)); if (line.match(/.*?\\/))
else if (line.match(/(if|elif|while|func|class|match)\s*\:/)) expectEndOfLine = true;
diagnostics.push(new vscode.Diagnostic(range, "Indentifier expected before ':'", DiagnosticSeverity.Error)); else if (line.match(/.*?\:[\s+]+[^#\s]+/))
else if (line.match(/[^\w]for[^\w]/) && !line.match(/\s+for\s\w+\s+in\s+|[\w+]|\{.*?\}|\[.*?\]|\(.*?\)/)){ return
if(!(line.match(/".*?for.*?"/) || line.match(/'.*?for.*?'/))) else if (!line.match(/.*?(\\|\:)/))
diagnostics.push(new vscode.Diagnostic(range, "Invalid for expression", DiagnosticSeverity.Error)); diagnostics.push(new vscode.Diagnostic(range, "': or \\' expected at end of the line.", DiagnosticSeverity.Error));
} else if (line.match(/\s(if|elif|while|func|class|match)\s*\:/))
else if (line.match(/(if|elif|while|match)\s*\(.*\)/)) diagnostics.push(new vscode.Diagnostic(range, "Indentifier expected before ':'", DiagnosticSeverity.Error));
diagnostics.push(new vscode.Diagnostic(range, "Extra brackets in condition expression.", DiagnosticSeverity.Warning)); else if (line.match(/[^\w]for[^\w]/) && !line.match(/\s+for\s\w+\s+in\s+|[\w+]|\{.*?\}|\[.*?\]|\(.*?\)/)){
const blockIndetCheck = function() { if(!(line.match(/".*?for.*?"/) || line.match(/'.*?for.*?'/)))
const err = new vscode.Diagnostic(range, "Expected indented block after expression", DiagnosticSeverity.Error); diagnostics.push(new vscode.Diagnostic(range, "Invalid for expression", DiagnosticSeverity.Error));
if (i < lines.length - 1) { }
let next = i + 1; else if (cfg.conditionBrackets && line.match(/\s(if|elif|while|match)\s*\(.*\)\s*:\s*$/))
let nextline = lines[next]; diagnostics.push(new vscode.Diagnostic(range, "Extra brackets in condition expression.", DiagnosticSeverity.Warning));
// changes nextline until finds a line containg text or comes to the last line const blockIndetCheck = function() {
while (((!nextline || !nextline.trim().length) || nextline.match(/^\s*#/)) && next < lines.length - 1) { const err = new vscode.Diagnostic(range, "Expected indented block after expression", DiagnosticSeverity.Error);
++next; if (i < lines.length - 1) {
nextline = lines[next]; let next = i + 1;
} let nextline = lines[next];
let nextLineStartAt = -1; // changes nextline until finds a line containg text or comes to the last line
let match = /[^\s]+.*/.exec(nextline); while (((!nextline || !nextline.trim().length) || nextline.match(/^\s*#/)) && next < lines.length - 1) {
if (match) ++next;
nextLineStartAt = match.index; nextline = lines[next];
}
if (nextLineStartAt <= curLineStartAt) let nextLineStartAt = -1;
diagnostics.push(err); let match = /[^\s]+.*/.exec(nextline);
} if (match)
else if(line.match(/\:\s*$/)) nextLineStartAt = match.index;
diagnostics.push(err);
}; if (nextLineStartAt <= curLineStartAt)
if(!expectEndOfLine) diagnostics.push(err);
blockIndetCheck(); }
} else if(line.match(/\:\s*$/))
// Do not check : for end of statement as it breaks match statment diagnostics.push(err);
let endOfStateMentWithComma = false; };
if(endOfStateMentWithComma && !line.match(colonKeywords) && line.match(/\:\s*$/)) { if(!expectEndOfLine)
let showErr = true; blockIndetCheck();
if( i >= 1 ) { }
let previous = i - 1; // Do not check : for end of statement as it breaks match statment
let previousline = lines[previous]; let endOfStateMentWithComma = false;
while(previousline.match(/\\\s*$/) && previous>=1) { if(endOfStateMentWithComma && !line.match(colonKeywords) && line.match(/\:\s*$/)) {
--previous; let showErr = true;
const ppreviousline = lines[previous]; if( i >= 1 ) {
if(ppreviousline.match(/\\\s*$/)) let previous = i - 1;
previousline = ppreviousline; let previousline = lines[previous];
} while(previousline.match(/\\\s*$/) && previous>=1) {
const keywords = previousline.match(colonKeywords); --previous;
if(keywords && !(previousline.match(new RegExp(`".*?\\s${keywords[1]}\\s.*?"`)) || previousline.match(new RegExp(`'.*?\\s${keywords[1]}\\s.*?'`)) )) const ppreviousline = lines[previous];
showErr = false if(ppreviousline.match(/\\\s*$/))
} previousline = ppreviousline;
if(showErr) }
diagnostics.push(new vscode.Diagnostic(range, "Expected end of statement after expression", DiagnosticSeverity.Error)); const keywords = previousline.match(colonKeywords);
} if(keywords && !(previousline.match(new RegExp(`".*?\\s${keywords[1]}\\s.*?"`)) || previousline.match(new RegExp(`'.*?\\s${keywords[1]}\\s.*?'`)) ))
if (line.match(/(if|elif|while|return)\s+\w+\s*=\s*\w+/)) showErr = false
diagnostics.push(new vscode.Diagnostic(range, "Assignment in condition or return expressions", DiagnosticSeverity.Warning)); }
else if (line.indexOf("==") > 0 && !line.match(/\:\s*/)) { if(showErr)
const endAt = line.indexOf("=="); diagnostics.push(new vscode.Diagnostic(range, "Expected end of statement after expression", DiagnosticSeverity.Error));
const precontent = line.substring(0, endAt); }
if (!precontent.match(/\s(if|elif|while|return)\s/) && !precontent.match(/=[^=]/) && !expectEndOfLine) { if (line.match(/(if|elif|while|return)\s+\w+\s*=\s*\w+/))
diagnostics.push(new vscode.Diagnostic(range, "Unhandled comparation expression contains", DiagnosticSeverity.Warning)); diagnostics.push(new vscode.Diagnostic(range, "Assignment in condition or return expressions", DiagnosticSeverity.Warning));
} else if (line.indexOf("==") > 0 && !line.match(/\:\s*/)) {
} const endAt = line.indexOf("==");
let match = /var\s+(\w+)\s*=\s*(\w+)/.exec(line); const precontent = line.substring(0, endAt);
if (match && match.length > 2 && match[1].length > 0 && match[1] == match[2]) { if (!precontent.match(/\s(if|elif|while|return)\s/) && !precontent.match(/=[^=]/) && !precontent.match(/assert\s*\(/) && !expectEndOfLine) {
diagnostics.push(new vscode.Diagnostic(range, "Self Assignment may cause error.", DiagnosticSeverity.Warning)); diagnostics.push(new vscode.Diagnostic(range, "Unhandled comparation expression contains", DiagnosticSeverity.Warning));
} }
}); }
return diagnostics; let match = /var\s+(\w+)\s*=\s*(\w+)/.exec(line);
} if (match && match.length > 2 && match[1].length > 0 && match[1] == match[2]) {
diagnostics.push(new vscode.Diagnostic(range, "Self Assignment may cause error.", DiagnosticSeverity.Warning));
} }
});
export default GDScriptDiagnosticSeverity; return diagnostics;
}
}
export default GDScriptDiagnosticSeverity;

View File

@@ -44,16 +44,19 @@ class GDScriptHoverProvider implements HoverProvider {
// check from workspace // check from workspace
const genWorkspaceTips = ()=> { const genWorkspaceTips = ()=> {
for (let path of Object.keys(workspaceSymbols)) { for (let filepath of Object.keys(workspaceSymbols)) {
const script = workspaceSymbols[path]; const script = workspaceSymbols[filepath];
let scriptips: MarkdownString[] = []; let scriptips: MarkdownString[] = [];
const getHoverText = (items, type, path): MarkdownString[] => { const getHoverText = (items, type, gdpath): MarkdownString[] => {
const _items: MarkdownString[] = []; const _items: MarkdownString[] = [];
for (let name of Object.keys(items)) { for (let name of Object.keys(items)) {
if (name == hoverText) { if (name == hoverText) {
let dfile = path; let dfile = gdpath;
if (workspace && workspace.asRelativePath(dfile)) if (workspace) {
dfile = workspace.asRelativePath(dfile); const root = config.normalizePath(workspace.rootPath) + "/";
if (gdpath.startsWith(root))
dfile = gdpath.replace(root, "");
}
let signature = ""; let signature = "";
if(type == "func"|| type == "signal" && script.signatures[name]) if(type == "func"|| type == "signal" && script.signatures[name])
signature = script.signatures[name]; signature = script.signatures[name];
@@ -65,21 +68,21 @@ class GDScriptHoverProvider implements HoverProvider {
rowDoc += "```plaintext\r\n"+rowDoc+"\r\n```"; rowDoc += "```plaintext\r\n"+rowDoc+"\r\n```";
doc += rowDoc; doc += rowDoc;
doc = doc?doc+"\r\n\r\n":""; doc = doc?doc+"\r\n\r\n":"";
if(path != "autoload") if(gdpath != "autoload")
doc += `*Defined in [${dfile}](${Uri.file(path).toString()})*`; doc += `*Defined in [${dfile}](${Uri.file(gdpath).toString()})*`;
_items.push(makeMarkdown(doc)); _items.push(makeMarkdown(doc));
break; break;
} }
} }
return _items; return _items;
} }
scriptips = [...scriptips, ...getHoverText(script.variables, 'var', path)]; scriptips = [...scriptips, ...getHoverText(script.variables, 'var', filepath)];
scriptips = [...scriptips, ...getHoverText(script.constants, 'const', path)]; scriptips = [...scriptips, ...getHoverText(script.constants, 'const', filepath)];
scriptips = [...scriptips, ...getHoverText(script.functions, 'func', path)]; scriptips = [...scriptips, ...getHoverText(script.functions, 'func', filepath)];
scriptips = [...scriptips, ...getHoverText(script.signals, 'signal', path)]; scriptips = [...scriptips, ...getHoverText(script.signals, 'signal', filepath)];
scriptips = [...scriptips, ...getHoverText(script.classes, 'class', path)]; scriptips = [...scriptips, ...getHoverText(script.classes, 'class', filepath)];
if(script.enumerations) if(script.enumerations)
scriptips = [...scriptips, ...getHoverText(script.enumerations, 'const', path)]; scriptips = [...scriptips, ...getHoverText(script.enumerations, 'const', filepath)];
tips = [...tips, ...scriptips]; tips = [...tips, ...scriptips];
} }
}; };
@@ -153,18 +156,18 @@ class GDScriptHoverProvider implements HoverProvider {
switch (item.kind) { switch (item.kind) {
case CompletionItemKind.Class: case CompletionItemKind.Class:
return makeMarkdown(`Native Class ${genLink(classname, classname)} ${doc}`); return makeMarkdown(`Native Class ${genLink(classname, classname)}\n${doc}`);
case CompletionItemKind.Method: case CompletionItemKind.Method:
doc = doc.substring(doc.indexOf("\n")+1, doc.length); doc = doc.substring(doc.indexOf("\n")+1, doc.length);
return makeMarkdown(`${genMethodMarkDown()} ${doc}`); return makeMarkdown(`${genMethodMarkDown()}\n${doc}`);
case CompletionItemKind.Interface: case CompletionItemKind.Interface:
doc = doc.substring(doc.indexOf("\n")+1, doc.length); doc = doc.substring(doc.indexOf("\n")+1, doc.length);
return makeMarkdown(`signal + ${genMethodMarkDown()} ${doc}`); return makeMarkdown(`signal ${genMethodMarkDown()}\n${doc}`);
case CompletionItemKind.Variable: case CompletionItemKind.Variable:
case CompletionItemKind.Property: case CompletionItemKind.Property:
return makeMarkdown(`${rowDoc.type} ${genLink(classname, classname)}.${genLink(rowDoc.name, classname+"."+rowDoc.name)} ${doc}`); return makeMarkdown(`${rowDoc.type} ${genLink(classname, classname)}.${genLink(rowDoc.name, classname + "." + rowDoc.name)}\n${doc}`);
case CompletionItemKind.Enum: case CompletionItemKind.Enum:
return makeMarkdown(`const ${genLink(classname, classname)}.${genLink(rowDoc.name, classname+"."+rowDoc.name)} = ${rowDoc.value} ${doc}`); return makeMarkdown(`const ${genLink(classname, classname)}.${genLink(rowDoc.name, classname + "." + rowDoc.name)} = ${rowDoc.value}\n${doc}`);
default: default:
break; break;
} }

View File

@@ -18,21 +18,22 @@ class ToolManager {
private workspacesymbolprovider: GDScriptWorkspaceSymbolProvider = null; private workspacesymbolprovider: GDScriptWorkspaceSymbolProvider = null;
private _disposable: vscode.Disposable; private _disposable: vscode.Disposable;
private _context: vscode.ExtensionContext; private _context: vscode.ExtensionContext;
private _projectFile : string = "engine.cfg"; private _projectFile : string = "project.godot";
private _rootDir : string = ""; private _rootDir : string = "";
private _biuitinDocFile : string = "doc/classes-2.1.json"; private _biuitinDocFile : string = "doc/classes-3.0.json";
constructor(context: vscode.ExtensionContext) { constructor(context: vscode.ExtensionContext) {
this._context = context; this._context = context;
this.workspaceDir = vscode.workspace.rootPath; this.workspaceDir = vscode.workspace.rootPath;
let completionDollar = false; let completionDollar = false;
if (vscode.workspace.getConfiguration("GodotTools").get("godotVersion", 2.1) >= 3) { if (vscode.workspace.getConfiguration("GodotTools").get("godotVersion", 3.0) < 3) {
this._projectFile = "project.godot"; this._projectFile = "engine.cfg";
this._biuitinDocFile = "doc/classes-3.0.json"; this._biuitinDocFile = "doc/classes-2.1.json";
completionDollar = true; completionDollar = true;
this.loadClasses();
} }
this.loadClasses();
if (vscode.workspace && this.workspaceDir) { if (vscode.workspace && this.workspaceDir) {
vscode.workspace.registerTextDocumentContentProvider('godotdoc', new GDScriptDocumentContentProvider()); vscode.workspace.registerTextDocumentContentProvider('godotdoc', new GDScriptDocumentContentProvider());
this.workspaceDir = this.workspaceDir.replace(/\\/g, "/"); this.workspaceDir = this.workspaceDir.replace(/\\/g, "/");
@@ -77,12 +78,12 @@ class ToolManager {
if (path && path.length > 0 && path.endsWith("/")) if (path && path.length > 0 && path.endsWith("/"))
path = path.substring(0, path.length - 1) path = path.substring(0, path.length - 1)
if (path.toLowerCase() == self.workspaceDir.toLowerCase()) if (path.toLowerCase() == self.workspaceDir.toLowerCase())
vscode.window.showInformationMessage("Connected to godot editor server"); vscode.window.showInformationMessage("Connected to the Godot editor server");
else { else {
vscode.window.showWarningMessage("The opened project is not same with godot editor"); vscode.window.showWarningMessage("The opened project is not the same within the Godot editor");
} }
}).catch(e => { }).catch(e => {
vscode.window.showErrorMessage("Failed connect to godot editor server"); vscode.window.showErrorMessage("Failed connecting to the Godot editor server");
}); });
} }
@@ -123,7 +124,7 @@ class ToolManager {
gdpath = path.join(this._rootDir, gdpath); gdpath = path.join(this._rootDir, gdpath);
let showgdpath = vscode.workspace.asRelativePath(gdpath); let showgdpath = vscode.workspace.asRelativePath(gdpath);
let doc = "Auto loaded instance of " + `[${showgdpath}](${vscode.Uri.file(gdpath).toString()})`; let doc = "Autoloaded instance of " + `[${showgdpath}](${vscode.Uri.file(gdpath).toString()})`;
doc = doc.replace(/"/g, " "); doc = doc.replace(/"/g, " ");
script.constants[name] = new vscode.Range(0, 0, 0, 0); script.constants[name] = new vscode.Range(0, 0, 0, 0);
@@ -156,13 +157,16 @@ class ToolManager {
} }
private loadWorkspaceSymbols() { private loadWorkspaceSymbols() {
let handle = this.showProgress("Loading symbols");
if (vscode.workspace.getConfiguration("GodotTools").get("parseTextScene", false)) { if (vscode.workspace.getConfiguration("GodotTools").get("parseTextScene", false)) {
this.loadAllNodesInWorkspace(); this.loadAllNodesInWorkspace();
} }
this.loadAllSymbols().then(symbols => { this.loadAllSymbols().then(symbols => {
handle();
vscode.window.setStatusBarMessage("$(check) Workspace symbols", 5000); vscode.window.setStatusBarMessage("$(check) Workspace symbols", 5000);
config.setAllSymbols(symbols); config.setAllSymbols(symbols);
}).catch(e => { }).catch(e => {
handle();
vscode.window.setStatusBarMessage("$(x) Workspace symbols", 5000); vscode.window.setStatusBarMessage("$(x) Workspace symbols", 5000);
}); });
} }
@@ -179,10 +183,10 @@ class ToolManager {
let pathFlag = "-path"; let pathFlag = "-path";
if (vscode.workspace.getConfiguration("GodotTools").get("godotVersion", 2.1) >= 3) if (vscode.workspace.getConfiguration("GodotTools").get("godotVersion", 2.1) >= 3)
pathFlag = "--path"; pathFlag = "--path";
this.runEditor(`${pathFlag} ${this._rootDir} ${params}`); this.runEditor(`${pathFlag} "${this._rootDir}" ${params}`);
} }
else else
vscode.window.showErrorMessage("Current workspace is not a godot project"); vscode.window.showErrorMessage("Current workspace is not a Godot project");
} }
private runEditor(params = "") { private runEditor(params = "") {
@@ -192,8 +196,13 @@ class ToolManager {
if (!fs.existsSync(editorPath) || !fs.statSync(editorPath).isFile()) { if (!fs.existsSync(editorPath) || !fs.statSync(editorPath).isFile()) {
vscode.window.showErrorMessage("Invalid editor path to run the project"); vscode.window.showErrorMessage("Invalid editor path to run the project");
} else { } else {
let terminal = vscode.window.createTerminal("Godot"); let existingTerminal = vscode.window.terminals.find(t => t._name === "GodotTools")
let cmmand = `${editorPath.replace(" ", "\\ ")} ${params}`; if (existingTerminal) {
existingTerminal.dispose()
}
let terminal = vscode.window.createTerminal("GodotTools");
editorPath = this.escapeCmd(editorPath);
let cmmand = `${editorPath} ${params}`;
terminal.sendText(cmmand, true); terminal.sendText(cmmand, true);
terminal.show(); terminal.show();
} }
@@ -214,7 +223,7 @@ class ToolManager {
const script = config.loadSymbolsFromFile(absFilePath); const script = config.loadSymbolsFromFile(absFilePath);
if (script) { if (script) {
if(script.native == "SceneTree" || script.native == "MainLoop") { if(script.native == "SceneTree" || script.native == "MainLoop") {
this.runEditor(`-s ${absFilePath}`); this.runEditor(`-s "${absFilePath}"`);
return; return;
} }
} }
@@ -222,9 +231,9 @@ class ToolManager {
} }
if (scenePath) { if (scenePath) {
if (scenePath.endsWith(".gd")) if (scenePath.endsWith(".gd"))
scenePath = ` -s res://${scenePath} `; scenePath = ` -s "res://${scenePath}" `;
else else
scenePath = ` res://${scenePath} `; scenePath = ` "res://${scenePath}" `;
this.openWorkspaceWithEditor(scenePath); this.openWorkspaceWithEditor(scenePath);
} else } else
vscode.window.showErrorMessage("Current document is not a scene file or MainLoop"); vscode.window.showErrorMessage("Current document is not a scene file or MainLoop");
@@ -237,12 +246,38 @@ class ToolManager {
if (!done) if (!done)
done = config.loadClasses(path.join(this._context.extensionPath, this._biuitinDocFile)); done = config.loadClasses(path.join(this._context.extensionPath, this._biuitinDocFile));
if (!done) if (!done)
vscode.window.showErrorMessage("Load GDScript documentations failed"); vscode.window.showErrorMessage("Loading GDScript documentation failed");
} }
dispose() { dispose() {
this._disposable.dispose(); this._disposable.dispose();
} }
private showProgress(message: string) {
let r_resolve;
vscode.window.withProgress({ location: vscode.ProgressLocation.Window}, p => {
return new Promise((resolve, reject) => {
p.report({message});
r_resolve = resolve;
});
});
return r_resolve;
}
private escapeCmd(cmd: string) {
// Double quote command (should work in at least cmd.exe and bash)
let cmdEsc = `"${cmd}"`;
// Fetch Windows shell type
let shell = vscode.workspace.getConfiguration("terminal.integrated.shell").get("windows", "");
// For powershell we prepend an & to prevent the command being treated as a string
if (shell.endsWith("powershell.exe") && process.platform === "win32") {
cmdEsc = `&${cmdEsc}`;
}
return cmdEsc
}
}; };
export default ToolManager; export default ToolManager;

View File

@@ -1,3 +1,4 @@
import * as vscode from 'vscode';
import {Disposable, window} from 'vscode'; import {Disposable, window} from 'vscode';
import GDScriptDiagnosticSeverity from './gdscript/diagnostic'; import GDScriptDiagnosticSeverity from './gdscript/diagnostic';
import GDScriptCompleter from './gdscript/completion'; import GDScriptCompleter from './gdscript/completion';
@@ -40,7 +41,9 @@ class WindowWatcher {
if(window.activeTextEditor != undefined) { if(window.activeTextEditor != undefined) {
const doc = window.activeTextEditor.document; const doc = window.activeTextEditor.document;
const script = config.loadSymbolsFromFile(doc.fileName); const script = config.loadSymbolsFromFile(doc.fileName);
this._diagnosticSeverity.validateScript(doc, script).then(()=>{}); if (vscode.workspace.getConfiguration("GodotTools").get("enableSyntaxChecking", true)) {
this._diagnosticSeverity.validateScript(doc, script).then(()=>{});
}
this._lastText = {path: doc.fileName, version: doc.version}; this._lastText = {path: doc.fileName, version: doc.version};
} }
} }
@@ -55,7 +58,9 @@ class WindowWatcher {
// Check content changed // Check content changed
if(this._lastText.path != curText.path || this._lastText.version != curText.version) { if(this._lastText.path != curText.path || this._lastText.version != curText.version) {
const script = config.loadSymbolsFromFile(doc.fileName); const script = config.loadSymbolsFromFile(doc.fileName);
this._diagnosticSeverity.validateScript(doc, script).then(()=>{}); if (vscode.workspace.getConfiguration("GodotTools").get("enableSyntaxChecking", true)) {
this._diagnosticSeverity.validateScript(doc, script).then(()=>{});
}
this._lastText = curText; this._lastText = curText;
} }
} }