diff --git a/src/config.ts b/src/config.ts index 17973d0..2d8c396 100644 --- a/src/config.ts +++ b/src/config.ts @@ -178,7 +178,6 @@ class Config { } loadScene(scenePath: string) { - console.log(scenePath); if(fs.existsSync(scenePath) && fs.statSync(scenePath).isFile()) { try { const content: string = fs.readFileSync(scenePath, 'utf-8'); diff --git a/src/gdscript/definitionprovider.ts b/src/gdscript/definitionprovider.ts new file mode 100644 index 0000000..f5521fe --- /dev/null +++ b/src/gdscript/definitionprovider.ts @@ -0,0 +1,93 @@ +import { + DefinitionProvider, + TextDocument, + Position, + CancellationToken, + Definition, + Location, + workspace, + Uri, + Range +} from 'vscode'; +import * as path from 'path'; +import * as fs from 'fs'; +import config from '../config'; + +class GDScriptDefinitionProivder implements DefinitionProvider { + constructor() { + + } + + provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Definition | Thenable < Definition > { + const isStr = (content:string) => (content.startsWith("'") || content.startsWith('"') || content.startsWith('@"') ) && (content.endsWith("'") || content.endsWith('"')); + const getSelectedContent = ():string =>{ + const line = document.lineAt(position); + const wordRange = document.getWordRangeAtPosition(position) ; + const machs = line.text.match(/[A-z_]+[A-z_0-9]*|".*"|'.*'|@".*"/g) + let res = line.text.substring(wordRange.start.character, wordRange.end.character); + machs.map(m=>{ + if(m) { + if(isStr(m)){ + res = m; + return; + } + } + }); + return res; + }; + const getDefinitions = (content: string):Location[]| Location => { + if(content.startsWith("res://")) { + content = content.replace("res://", ""); + if(workspace && workspace.rootPath) + content = path.join(workspace.rootPath, content) + return new Location(Uri.file(content), new Range(0,0,0,0)); + } + else if(fs.existsSync(content) && fs.statSync(content).isFile()) { + return new Location(Uri.file(content), new Range(0,0,0,0)); + } + else { + const workspaceSymbols = config.getAllSymbols(); + let locations: Location[] = []; + // check from workspace + for (let path of Object.keys(workspaceSymbols)) { + const script = workspaceSymbols[path]; + let scriptitems: Location[] = []; + const checkDifinition = (items)=>{ + const _items: Location[] = []; + for (let name of Object.keys(items)) { + if(name == content) { + _items.push(new Location(Uri.file(path), items[name])); + } + } + return _items; + } + scriptitems = [...scriptitems, ...checkDifinition(script.variables)]; + scriptitems = [...scriptitems, ...checkDifinition(script.constants)]; + scriptitems = [...scriptitems, ...checkDifinition(script.functions)]; + scriptitems = [...scriptitems, ...checkDifinition(script.signals)]; + scriptitems = [...scriptitems, ...checkDifinition(script.classes)]; + locations = [...locations, ...scriptitems]; + } + // check from builtin + return locations; + } + }; + + + let selStr = getSelectedContent(); + if(selStr) { + // For strings + if(isStr(selStr)) { + selStr = selStr.replace(/"|'|@"/g,""); + let fpath = path.join(path.dirname(document.uri.fsPath), selStr) + console.log(fpath); + if(fs.existsSync(fpath) && fs.statSync(fpath).isFile()) + selStr = fpath + } + return getDefinitions(selStr); + } + return null; + } +} + +export default GDScriptDefinitionProivder; \ No newline at end of file diff --git a/src/tool_manager.ts b/src/tool_manager.ts index eeff5ee..cd7c9f8 100644 --- a/src/tool_manager.ts +++ b/src/tool_manager.ts @@ -3,6 +3,7 @@ import godotRequest from './request'; import GDScriptSymbolProvider from './gdscript/symbolprovider'; import GDScriptWorkspaceSymbolProvider from './gdscript/workspace_symbol_provider'; import GDScriptCompletionItemProvider from './gdscript/completion'; +import GDScriptDefinitionProivder from './gdscript/definitionprovider'; var glob = require("glob") import config from './config'; import * as path from 'path'; @@ -34,6 +35,8 @@ class ToolManager { // workspace symbol provider this.workspacesymbolprovider = new GDScriptWorkspaceSymbolProvider(); vscode.languages.registerWorkspaceSymbolProvider(this.workspacesymbolprovider); + // definition provider + vscode.languages.registerDefinitionProvider('gdscript', new GDScriptDefinitionProivder()); // code completion provider vscode.languages.registerCompletionItemProvider('gdscript', new GDScriptCompletionItemProvider(), '.', '"', "'"); // Commands