load docdata for codecompletion

This commit is contained in:
Geequlim
2016-12-25 00:56:40 +08:00
parent b75178f500
commit bb5e48dddf
4 changed files with 111 additions and 123 deletions

View File

@@ -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();

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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();
}