From bb5e48dddfadb7699173390bcb49f70ae4ba4a08 Mon Sep 17 00:00:00 2001 From: Geequlim Date: Sun, 25 Dec 2016 00:56:40 +0800 Subject: [PATCH] load docdata for codecompletion --- src/config.ts | 69 ++++++++++++++++++++++++++++++ src/docdata.ts | 87 -------------------------------------- src/gdscript/completion.ts | 64 ++++++++++++++-------------- src/tool_manager.ts | 14 ++++-- 4 files changed, 111 insertions(+), 123 deletions(-) delete mode 100644 src/docdata.ts diff --git a/src/config.ts b/src/config.ts index b030757..2814bc0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -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(); \ No newline at end of file diff --git a/src/docdata.ts b/src/docdata.ts deleted file mode 100644 index 334d707..0000000 --- a/src/docdata.ts +++ /dev/null @@ -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 { - 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; \ No newline at end of file diff --git a/src/gdscript/completion.ts b/src/gdscript/completion.ts index c496ec4..96f0b17 100644 --- a/src/gdscript/completion.ts +++ b/src/gdscript/completion.ts @@ -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() { diff --git a/src/tool_manager.ts b/src/tool_manager.ts index 01c4e9a..af8071e 100644 --- a/src/tool_manager.ts +++ b/src/tool_manager.ts @@ -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(); }