Refact the code validating and codecompletion

This commit is contained in:
Geequlim
2016-12-15 22:12:38 +08:00
parent 89c2a60f5b
commit b420fde137
18 changed files with 338 additions and 2557 deletions

View File

@@ -1,56 +1,54 @@
{
"name": "godot-tools",
"displayName": "godot-tools",
"description": "\"Tools for game development with godot game engine\"",
"version": "0.0.1",
"publisher": "GodotExplorer",
"engines": {
"vscode": "^1.5.0"
},
"categories": [
"Other"
"name": "godot-tools",
"displayName": "Godot Tools",
"description": "\"Tools for game development with godot game engine\"",
"version": "0.1.0",
"publisher": "GodotExplorer",
"engines": {
"vscode": "^1.5.0"
},
"categories": [
"Other"
],
"activationEvents": [
"workspaceContains:engine.cfg"
],
"main": "./out/src/extension",
"contributes": {
"commands": [
{
"command": "extension.sayHello",
"title": "Hello World"
}
],
"activationEvents": [
"onLanguage:gdscript",
"workspaceContains:engine.cfg"
],
"main": "./out/src/extension",
"contributes": {
"commands": [{
"command": "extension.sayHello",
"title": "Hello World"
}],
"configuration": {
"type": "object",
"title": "Godot tools configuration",
"properties": {
"GDScriptServer.editorServerPort": {
"type": "number",
"default": 6996,
"description": "The server port of your EditorServer"
},
"GDScriptServer.maxNumberOfProblems": {
"type": "number",
"default": 10,
"description": "Controls the maximum number of problems produced by the server."
}
}
"configuration": {
"type": "object",
"title": "Godot tools configuration",
"properties": {
"GDScriptServer.editorServerPort": {
"type": "number",
"default": 6996,
"description": "The server port of your EditorServer"
},
"GDScriptServer.maxNumberOfProblems": {
"type": "number",
"default": 10,
"description": "Controls the maximum number of problems produced by the server."
}
},
"scripts": {
"vscode:prepublish": "tsc -p ./",
"compile": "tsc -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "node ./node_modules/vscode/bin/test"
},
"devDependencies": {
"typescript": "^2.0.3",
"vscode": "^1.0.0",
"mocha": "^2.3.3",
"@types/node": "^6.0.40",
"@types/mocha": "^2.2.32"
},
"dependencies": {
"vscode-languageclient": "^2.6.3"
}
}
}
}
},
"scripts": {
"vscode:prepublish": "tsc -p ./",
"compile": "tsc -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "node ./node_modules/vscode/bin/test"
},
"devDependencies": {
"typescript": "^2.0.3",
"vscode": "^1.0.0",
"mocha": "^2.3.3",
"@types/node": "^6.0.40",
"@types/mocha": "^2.2.32"
}
}

View File

@@ -1,15 +1,10 @@
'use strict';
import * as path from 'path';
import GDScriptClient from './gdscript/client';
import { workspace, Disposable, ExtensionContext } from 'vscode';
import * as vscode from "vscode";
import { LanguageClient } from 'vscode-languageclient';
let gdclient: GDScriptClient = null;
import WindowWatch from "./window_watcher";
export function activate(context: ExtensionContext) {
gdclient = new GDScriptClient(context);
let disposable = gdclient.createLanguageClient().start();
context.subscriptions.push(disposable);
context.subscriptions.push(new WindowWatch());
console.log("[GodotTools]: Extension Activated");
}

View File

@@ -1,67 +0,0 @@
import * as path from 'path';
import {
LanguageClientOptions,
ServerOptions,
LanguageClient,
TransportKind,
NotificationType,
NotificationHandler
} from 'vscode-languageclient';
import {
workspace,
ExtensionContext
} from 'vscode';
/**
* GDScriptClient
*/
class GDScriptClient {
private client_options: LanguageClientOptions;
private server_options: ServerOptions;
private context: ExtensionContext;
constructor(context: ExtensionContext) {
this.context = context;
this.client_options = {
// Register the server for gdscript documents
documentSelector: ['gdscript'],
synchronize: {
// Synchronize the setting section 'languageServerExample' to the server
configurationSection: 'GDScriptServer',
// Notify the server about file changes to *.gd files contain in the workspace
fileEvents: workspace.createFileSystemWatcher('*.gd')
}
};
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'server.js'));
// The debug options for the server
let debugOptions = {
execArgv: ["--nolazy", "--debug=6980"]
};
this.server_options = {
run: {
module: serverModule,
transport: TransportKind.ipc
},
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions
}
};
}
public createLanguageClient(): LanguageClient {
const lc = new LanguageClient('GDScriptLanguage', this.server_options, this.client_options);
lc.onNotification < string > ({method:"notify"}, this.onNotification.bind(this));
return lc;
}
public onNotification(param: any) {
console.log(param);
}
}
export default GDScriptClient;

View File

@@ -0,0 +1,90 @@
import {
CompletionItemProvider,
Position,
TextDocument,
CancellationToken,
CompletionItem,
CompletionList,
languages,
Disposable,
CompletionItemKind
} from 'vscode';
import requestGodot from '../request';
interface CompleteRequest {
path: string,
text: string,
cursor: {
row: number,
column: number
}
}
interface CompletionResult {
suggestions: string[],
hint: string,
prefix: string,
valid: boolean
}
class GDScriptCompletionItemProvider implements CompletionItemProvider {
constructor() {
}
provideCompletionItems(document : TextDocument, position : Position, token : CancellationToken) : CompletionItem[] | Thenable < CompletionItem[] > | CompletionList | Thenable < CompletionList > {
// console.log("[GodotTools]:provideCompletionItems");
const request: CompleteRequest = {
path: document.fileName,
text: document.getText(),
cursor: {
row: position.line + 1,
column: position.character + 1
}
};
return new Promise((resolve, reject) => {
requestGodot({
action: "codecomplete",
request
}).then((data: any)=>{
const result: CompletionResult = data.result;
if(result && result.suggestions && result.suggestions.length > 0) {
const items:CompletionItem[] = [];
result.suggestions.map((label, i)=>{
items.push(new CompletionItem(label, CompletionItemKind.Field));
});
resolve(items);
}
else
reject("Nothing to complete");
}).catch(e=>{
reject(e);
});
});
}
resolveCompletionItem(item : CompletionItem, token : CancellationToken) : CompletionItem | Thenable < CompletionItem > {
return item;
}
}
class GDScriptCompleter {
private _provider: Disposable;
constructor() {
this._provider = languages.registerCompletionItemProvider('gdscript',
new GDScriptCompletionItemProvider(),
'.', '\'','\"','(', '_',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
);
}
dispose() {
this._provider.dispose();
}
}
export default GDScriptCompleter;

77
src/gdscript/parser.ts Normal file
View File

@@ -0,0 +1,77 @@
import requestGodot from "../request";
import * as vscode from 'vscode';
import {DiagnosticCollection, DiagnosticSeverity} from 'vscode';
interface GDParseError {
message: string,
column: number,
row: number
}
interface GDScript {
members: {
constants: {},
functions: {},
variables: {},
signals: {}
},
base: string,
errors: GDParseError[],
valid: boolean,
is_tool: boolean,
native: string
}
interface ParseRequest {
text: string,
path: string
}
class GDParser {
private _subscription: DiagnosticCollection;
constructor() {
this._subscription = vscode.languages.createDiagnosticCollection("gdscript")
}
dispose() {
this._subscription.dispose()
}
private parseGDScript(script: GDScript, request: ParseRequest) {
// console.log("Parse GDScript ", script);
let canonicalFile = vscode.Uri.file(request.path);
this._subscription.delete(canonicalFile)
if(script.valid) { // Parse symbols
}
if(script.errors.length != 0 ) { // Parse errors
let diagnostics = [];
script.errors.map( error => {
let range = new vscode.Range(error.row-1, error.column, error.row-1, error.row + 10);
diagnostics.push(new vscode.Diagnostic(range, error.message, DiagnosticSeverity.Error));
});
this._subscription.set(canonicalFile, diagnostics);
}
}
parseDocument(doc: vscode.TextDocument) {
if(doc.languageId == 'gdscript') {
// console.log('[GodotTools]:start parsing document ', doc);
const self = this;
const request: ParseRequest = {text: doc.getText(), path: doc.fileName};
requestGodot({action: "parsescript",request}).then((data: any)=>{
const result: GDScript = data.result;
if(result && vscode.window.activeTextEditor.document == doc){
self.parseGDScript(result, request);
}
}).catch(e=>{
console.error(e);
});
}
}
}
export default GDParser;

View File

@@ -1,2 +0,0 @@
out
node_modules

View File

@@ -1,14 +0,0 @@
{
"version": "0.1.0",
// List of configurations. Add new configurations or edit existing ones.
"configurations": [
{
"name": "Attach",
"type": "node",
"request": "attach",
"port": 6980,
"sourceMaps": true,
"outDir": "${workspaceRoot}/../../../server"
}
]
}

View File

@@ -1,9 +0,0 @@
{
"version": "0.1.0",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"args": ["run", "watch"],
"isWatching": true,
"problemMatcher": "$tsc-watch"
}

View File

@@ -1,11 +0,0 @@
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,3 +0,0 @@
#README
This is a language server sample implementation in node

View File

@@ -1,31 +0,0 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
For Microsoft vscode-languageserver-node-example
This project incorporates material from the project(s) listed below (collectively, “Third Party Code”).
Microsoft is not the original author of the Third Party Code. The original copyright notice and license
under which Microsoft received such Third Party Code are set out below. This Third Party Code is licensed
to you under their original license terms set forth below. Microsoft reserves all other rights not expressly
granted, whether by implication, estoppel or otherwise.
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
This project is licensed under the MIT license.
Copyrights are respective of each contributor listed at the beginning of each definition file.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,20 +0,0 @@
{
"name": "language-server-example",
"description": "Example implementation of a language server in node.",
"version": "0.0.1",
"author": "Microsoft Corporation",
"license": "MIT",
"engines": {
"node": "*"
},
"dependencies": {
"vscode-languageserver": "^2.2.0"
},
"devDependencies": {
"typescript": "^1.8.9"
},
"scripts": {
"compile": "installServerIntoExtension ../../../ ./package.json ./tsconfig.json && tsc -p .",
"watch": "installServerIntoExtension ../../../ ./package.json ./tsconfig.json && tsc --watch -p ."
}
}

View File

@@ -1,136 +0,0 @@
'use strict';
import {
IPCMessageReader, IPCMessageWriter,
createConnection, IConnection, TextDocumentSyncKind,
TextDocuments, TextDocument, Diagnostic, DiagnosticSeverity,
InitializeParams, InitializeResult, TextDocumentPositionParams,
CompletionItem, CompletionItemKind
} from 'vscode-languageserver';
import request from "./request";
import validate from "./actions/gd_validate";
import CodeCompleter from './actions/gd_codecomplete';
let completer: CodeCompleter = null;
// Create a connection for the server. The connection uses Node's IPC as a transport
let connection: IConnection = createConnection(new IPCMessageReader(process), new IPCMessageWriter(process));
// Create a simple text document manager. The text document manager supports full document sync only
let documents: TextDocuments = new TextDocuments();
// Make the text document manager listen on the connection for open, change and close text document events
documents.listen(connection);
// After the server has started the client sends an initilize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilites.
let workspaceRoot: string;
connection.onInitialize((params): InitializeResult => {
workspaceRoot = params.rootPath;
completer = new CodeCompleter();
return {
capabilities: {
// Tell the client that the server works in FULL text document sync mode
textDocumentSync: documents.syncKind,
// Tell the client that the server support code complete
completionProvider: {
resolveProvider: true,
triggerCharacters: [ '.', 'a', 'b', 'c', 'd', 'e', 'f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','(',
'_', 'A', 'B', 'C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\'','\"'
]
}
}
}
});
let doc = null;
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent((change) => {
doc = change.document;
validateTextDocument(doc);
});
// This handler provides the initial list of the completion items.
connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
let cursor = {row: textDocumentPosition.position.line+1, column:textDocumentPosition.position.character};
let items = [...completer.getItems()];
completer.query(doc.getText(), doc.uri, cursor);
return items;
});
// The settings interface describe the server relevant settings part
interface Settings {
GDScriptServer: ExampleSettings;
}
// These are the example settings we defined in the client's package.json
// file
interface ExampleSettings {
maxNumberOfProblems: number;
editorServerPort: number;
}
// hold the maxNumberOfProblems setting
let maxNumberOfProblems: number;
let editorServerPort: number;
// The settings have changed. Is send on server activation
// as well.
connection.onDidChangeConfiguration((change) => {
let settings = <Settings>change.settings;
maxNumberOfProblems = settings.GDScriptServer.maxNumberOfProblems || 10;
// editorServerPort: settings.GDScriptServer.editorServerPort || 6996;
documents.all().forEach(validateTextDocument);
});
function validateTextDocument(textDocument: TextDocument): void {
validate(textDocument.getText(), textDocument.uri, connection);
}
connection.onDidChangeWatchedFiles((change) => {
// Monitored files have change in VSCode
connection.console.log('We recevied an file change event');
});
// This handler resolve additional information for the item selected in
// the completion list.
connection.onCompletionResolve((item: CompletionItem): CompletionItem => {
// if (item.data === 1) {
// item.detail = 'TypeScript details',
// item.documentation = 'TypeScript documentation'
// } else if (item.data === 2) {
// item.detail = 'JavaScript details',
// item.documentation = 'JavaScript documentation'
// }
return item;
});
// connection.onDidOpenTextDocument((params) => {
// // A text document got opened in VSCode.
// // params.uri uniquely identifies the document. For documents store on disk this is a file URI.
// // params.text the initial full content of the document.
// connection.console.log(`${params.uri} opened.`);
// });
// connection.onDidChangeTextDocument((params) => {
// // The content of a text document did change in VSCode.
// // params.uri uniquely identifies the document.
// // params.contentChanges describe the content changes to the document.
// params.contentChanges
// connection.console.log(`${params.uri} changed: ${JSON.stringify(params.contentChanges)}`);
// });
// connection.onDidCloseTextDocument((params) => {
// // A text document got closed in VSCode.
// // params.uri uniquely identifies the document.
// connection.console.log(`${params.uri} closed.`);
// });
// Listen on the connection
connection.listen();

View File

@@ -1,12 +0,0 @@
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "../../../server"
},
"exclude": [
"node_modules"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,112 +0,0 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/**
* The Thenable (E.g. PromiseLike) and Promise declarions are taken from TypeScript's
* lib.core.es6.d.ts file. See above Copyright notice.
*/
/**
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
* and others. This API makes no assumption about what promise libary is being used which
* enables reusing existing code without migrating to a specific promise implementation. Still,
* we recommand the use of native promises which are available in VS Code.
*/
interface Thenable<R> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
}
/**
* Represents the completion of an asynchronous operation
*/
interface Promise<T> extends Thenable<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Promise<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
/**
* Attaches a callback for only the rejection of the Promise.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of the callback.
*/
catch(onrejected?: (reason: any) => T | Thenable<T>): Promise<T>;
}
interface PromiseConstructor {
/**
* Creates a new Promise.
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
* a resolve callback used resolve the promise with a value or the result of another promise,
* and a reject callback used to reject the promise with a provided reason or error.
*/
new <T>(executor: (resolve: (value?: T | Thenable<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
/**
* Creates a Promise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any Promise is rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
all<T>(values: Array<T | Thenable<T>>): Promise<T[]>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T>(values: Array<T | Thenable<T>>): Promise<T>;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected Promise.
*/
reject(reason: any): Promise<void>;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected Promise.
*/
reject<T>(reason: any): Promise<T>;
/**
* Creates a new resolved promise for the provided value.
* @param value A promise.
* @returns A promise whose internal state matches the provided promise.
*/
resolve<T>(value: T | Thenable<T>): Promise<T>;
/**
* Creates a new resolved promise .
* @returns A resolved promise.
*/
resolve(): Promise<void>;
}
declare var Promise: PromiseConstructor;

37
src/request.ts Normal file
View File

@@ -0,0 +1,37 @@
import * as http from 'http';
function requestGodot(body : Object) {
let postString = JSON.stringify(body);
const options = {
hostname: '127.0.0.1',
port: 6996,
method: 'POST',
headers: {
"Accept": "application/json",
"Connection": "keep-alive",
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(postString)
},
body
};
let promise = new Promise((resolve, reject) => {
var req = http.request(options, (res) => {
let resultString = "";
res.setEncoding('utf8');
res.on('data', (chunk) => {
resultString += chunk;
});
res.on('end', () => {
resolve(JSON.parse(resultString));
});
req.on('error', (e) => {
reject(e);
});
});
req.write(postString);
req.end();
});
return promise;
}
export default requestGodot;

80
src/window_watcher.ts Normal file
View File

@@ -0,0 +1,80 @@
import {Disposable, window} from 'vscode';
import parse from "./gdscript/parser";
import GDParser from './gdscript/parser';
import GDScriptCompleter from './gdscript/completion';
import * as path from 'path';
import * as fs from 'fs';
interface DocumentFlag {
path: string,
version: number
}
class WindowWatcher {
private _disposable: Disposable;
private _parser: GDParser;
private _lastText: DocumentFlag;
private _completer: GDScriptCompleter;
constructor() {
let subscriptions: Disposable[] = [];
window.onDidChangeTextEditorSelection(this.onDidChangeTextEditorSelection.bind(this), this, subscriptions);
window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor.bind(this), this, subscriptions);
window.onDidChangeTextEditorOptions(this.onDidChangeTextEditorOptions.bind(this), this, subscriptions);
window.onDidChangeTextEditorViewColumn(this.onDidChangeTextEditorViewColumn.bind(this), this, subscriptions);
this._parser = new GDParser();
this._completer = new GDScriptCompleter();
this._disposable = Disposable.from(...subscriptions, this._parser, this._completer);
this._lastText = {path: "-1", version: -1};
}
dispose() {
this._disposable.dispose();
}
/**
* Fires when the [active editor](#window.activeTextEditor)
* has changed. *Note* that the event also fires when the active editor changes
* to `undefined`.
*/
private onDidChangeActiveTextEditor(event: any) {
console.log("[GodotTools]:onDidChangeActiveTextEditor", event);
if(window.activeTextEditor != undefined) {
const doc = window.activeTextEditor.document;
this._parser.parseDocument(doc);
this._lastText = {path: doc.fileName, version: doc.version};
}
}
/**
* Fires when the selection in an editor has changed.
*/
private onDidChangeTextEditorSelection(event: any) {
console.log("[GodotTools]:onDidChangeTextEditorSelection");
const doc = window.activeTextEditor.document;
const curText: DocumentFlag= {path: doc.fileName, version: doc.version};
if(this._lastText.path != curText.path || this._lastText.version != curText.version) {
this._parser.parseDocument(doc);
this._lastText = curText;
}
}
/**
* Fires when the options of an editor have changed.
*/
private onDidChangeTextEditorOptions(event: any) {
console.log("[GodotTools]:onDidChangeTextEditorOptions", event);
}
/**
* Fires when the view column of an editor has changed.
*/
private onDidChangeTextEditorViewColumn(event: any) {
console.log("[GodotTools]:onDidChangeTextEditorViewColumn", event);
}
}
export default WindowWatcher;