mirror of
https://github.com/godotengine/godot-vscode-plugin.git
synced 2025-12-31 13:48:24 +03:00
load docdata for codecompletion
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
import GDScriptSymbolParser from './gdscript/symbolparser';
|
||||
import * as fs from 'fs';
|
||||
import {CompletionItem, CompletionItemKind, TextEdit, Range} from 'vscode';
|
||||
|
||||
class Config {
|
||||
private symbols;
|
||||
private classes;
|
||||
public bintinSybmolInfoList: CompletionItem[];
|
||||
public parser: GDScriptSymbolParser;
|
||||
|
||||
constructor() {
|
||||
this.symbols = {};
|
||||
this.bintinSybmolInfoList = [];
|
||||
this.parser = new GDScriptSymbolParser();
|
||||
}
|
||||
|
||||
@@ -42,6 +47,70 @@ class Config {
|
||||
return newpath;
|
||||
}
|
||||
|
||||
loadClasses(docfile: string): boolean {
|
||||
let done: boolean = false;
|
||||
try {
|
||||
if(fs.existsSync(docfile) && fs.statSync(docfile).isFile()) {
|
||||
const content = fs.readFileSync(docfile, "utf-8");
|
||||
const docdata = JSON.parse(content);
|
||||
if(docdata.classes) {
|
||||
this.classes = docdata.classes;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
if(done) {
|
||||
for (let key of Object.keys(this.classes)) {
|
||||
const classdoc = this.classes[key];
|
||||
const bintinSybmolInfoList = this.bintinSybmolInfoList;
|
||||
// class
|
||||
const item: CompletionItem = new CompletionItem(classdoc.name, CompletionItemKind.Class);
|
||||
item.detail = 'Native Class';
|
||||
item.documentation = classdoc.brief_description + " \n\n" +classdoc.description;
|
||||
bintinSybmolInfoList.push(item);
|
||||
// methods
|
||||
const methods = classdoc.methods
|
||||
const parsMethod = (m, kind: CompletionItemKind, insertAction=(name)=>name+"()")=>{
|
||||
const mi = new CompletionItem(m.name, kind);
|
||||
mi.insertText = insertAction(m.name)
|
||||
mi.filterText = m.name
|
||||
mi.sortText = m.name
|
||||
mi.detail = `${classdoc.name}.${m.name}`;
|
||||
let argstr = "";
|
||||
m.arguments.map(arg=>{
|
||||
argstr += `${arg.type} ${arg.name}${arg.default_value.length>0?'='+arg.default_value.length:''}${m.arguments.indexOf(arg)==m.arguments.length-1?'':', '}`;
|
||||
});
|
||||
let mdoc = `${m.return_type} ${classdoc.name}.${m.name}(${argstr}) ${m.qualifiers}`;
|
||||
mdoc += " \n\n";
|
||||
mdoc += m.description;
|
||||
mi.documentation = mdoc;
|
||||
bintinSybmolInfoList.push(mi);
|
||||
};
|
||||
methods.map(m=>parsMethod(m, CompletionItemKind.Method));
|
||||
// signals
|
||||
const signals = classdoc.signals;
|
||||
signals.map(s=>parsMethod(s, CompletionItemKind.Interface, (name)=>`"${name}"`));
|
||||
// constants
|
||||
const constants = classdoc.constants;
|
||||
constants.map(c=>{
|
||||
const ci = new CompletionItem(c.name, CompletionItemKind.Enum);
|
||||
ci.detail = c.value;
|
||||
ci.documentation = `${classdoc.name}.${c.name} = ${c.value}`;
|
||||
bintinSybmolInfoList.push(ci);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return done;
|
||||
};
|
||||
|
||||
getClass(name: string) {
|
||||
return this.classes[name];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default new Config();
|
||||
@@ -1,87 +0,0 @@
|
||||
"use strict";
|
||||
import * as fs from 'fs';
|
||||
import requestGodot from './request';
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import config from './config';
|
||||
|
||||
let version: string;
|
||||
let storageDir: string;
|
||||
let docdata: Object = null;
|
||||
|
||||
class DocDataManager {
|
||||
|
||||
constructor(dir: string) {
|
||||
version = "";
|
||||
storageDir = dir;
|
||||
// console.log(dir);
|
||||
// Load documents
|
||||
DocDataManager.getDocData().then(doc=>{
|
||||
docdata = doc;
|
||||
console.log("Godot Documentations loaded.");
|
||||
// vscode.window.showInformationMessage("Godot Documentations loaded.");
|
||||
}).catch(e=>{
|
||||
// console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
private static checkversion():Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (version != "")
|
||||
resolve(version)
|
||||
else {
|
||||
requestGodot({action: "editor", command: "version"}).then((res:any)=>{
|
||||
version = res.version;
|
||||
resolve(version);
|
||||
}).catch(e=>{
|
||||
reject(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static getDocData() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(docdata)
|
||||
resolve(docdata);
|
||||
else {
|
||||
DocDataManager.checkversion().then((version: string)=> {
|
||||
try {
|
||||
const dir = path.join(storageDir, "docs");
|
||||
if(!(fs.existsSync(dir)))
|
||||
fs.mkdirSync(dir)
|
||||
// Load docdata from file
|
||||
const loadDocdata = (docfile) => {
|
||||
const content = fs.readFileSync(docfile, "utf-8");
|
||||
if(content && content.length > 0) {
|
||||
docdata = JSON.parse(content);
|
||||
resolve(docdata);
|
||||
}
|
||||
else
|
||||
reject(new Error("Load Docdata failed!"));
|
||||
};
|
||||
const docfile: string = path.join(dir, version+".json")
|
||||
if(fs.existsSync(docfile) && fs.statSync(docfile).isFile())
|
||||
loadDocdata(docfile);
|
||||
else {
|
||||
requestGodot({action: "editor", command: "gendoc", path: config.normalizePath(docfile) }).then((res:any)=>{
|
||||
if(res && res.done)
|
||||
loadDocdata(docfile);
|
||||
else
|
||||
reject(new Error("Generate Docdata failed!"));
|
||||
}).catch(e=>{
|
||||
reject(new Error("Generate Docdata failed!"));
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error("Generate Docdata failed!"));
|
||||
}
|
||||
}).catch(e=> {
|
||||
reject(new Error("Get Docdata failed: cannot get version of your godot editor!"));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default DocDataManager;
|
||||
@@ -36,33 +36,36 @@ class GDScriptCompletionItemProvider implements CompletionItemProvider {
|
||||
|
||||
provideCompletionItems(document : TextDocument, position : Position, token : CancellationToken) : CompletionItem[] | Thenable < CompletionItem[] > | CompletionList | Thenable < CompletionList > {
|
||||
// console.log("[GodotTools]:provideCompletionItems");
|
||||
const request: CompleteRequest = {
|
||||
path: config.normalizePath(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);
|
||||
});
|
||||
});
|
||||
// const request: CompleteRequest = {
|
||||
// path: config.normalizePath(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);
|
||||
// });
|
||||
// });
|
||||
const items:CompletionItem[] = config.bintinSybmolInfoList;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
resolveCompletionItem(item : CompletionItem, token : CancellationToken) : CompletionItem | Thenable < CompletionItem > {
|
||||
@@ -75,12 +78,7 @@ class GDScriptCompletionItemProvider implements CompletionItemProvider {
|
||||
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'
|
||||
);
|
||||
this._provider = languages.registerCompletionItemProvider('gdscript', new GDScriptCompletionItemProvider(), '.');
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import * as vscode from 'vscode';
|
||||
import DocDataManager from './docdata';
|
||||
import godotRequest from './request';
|
||||
import GDScriptSymbolProvider from './gdscript/symbolprovider';
|
||||
import GDScriptWorkspaceSymbolProvider from './gdscript/workspace_symbol_provider';
|
||||
var glob = require("glob")
|
||||
import config from './config';
|
||||
import * as path from 'path';
|
||||
|
||||
class ToolManager {
|
||||
|
||||
private workspaceDir: string = "";
|
||||
private docs: DocDataManager = null;
|
||||
private symbolprovider: GDScriptSymbolProvider = null;
|
||||
private workspacesymbolprovider: GDScriptWorkspaceSymbolProvider = null;
|
||||
private _disposable: vscode.Disposable;
|
||||
@@ -18,7 +17,7 @@ class ToolManager {
|
||||
this.workspaceDir = vscode.workspace.rootPath.replace(/\\/g, "/");
|
||||
this.validate();
|
||||
this.loadWorkspaceSymbols();
|
||||
this.docs = new DocDataManager(context.extensionPath);
|
||||
this.loadClasses();
|
||||
this.symbolprovider = new GDScriptSymbolProvider();
|
||||
vscode.languages.registerDocumentSymbolProvider('gdscript', this.symbolprovider);
|
||||
this.workspacesymbolprovider = new GDScriptWorkspaceSymbolProvider();
|
||||
@@ -71,6 +70,15 @@ class ToolManager {
|
||||
});
|
||||
}
|
||||
|
||||
loadClasses() {
|
||||
if(config.loadClasses(path.join(this.workspaceDir, ".vscode", "classes.json"))) {
|
||||
vscode.window.showInformationMessage("Update GDScript documentations done");
|
||||
}
|
||||
else {
|
||||
vscode.window.showWarningMessage("Update GDScript documentations failed");
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposable.dispose();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user