diff --git a/src/navigation-data.ts b/src/navigation-data.ts index 1293b68..f73bc29 100644 --- a/src/navigation-data.ts +++ b/src/navigation-data.ts @@ -1,4 +1,4 @@ -import { commands, CompletionItem, CompletionItemKind, LogLevel, Position, TextDocument, window, workspace } from "vscode"; +import { commands, CompletionItem, CompletionItemKind, CompletionItemTag, LogLevel, MarkdownString, Position, SnippetString, TextDocument, window, workspace } from "vscode"; import { getDefinitionFromFile } from "./hover"; import { DataType, getBaseTypeFromDefine, getNamedParameter, getPyDocsFromTextDocumentAtLine, Navigation, splitParameters, stripQuotes } from "./navigation"; import { cleanUpPath, extractFilenameWithoutExtension, getFileWithPath, getNavigationJsonFilepath, stripWorkspaceFromFile } from "./workspace"; @@ -11,9 +11,19 @@ import { logMessage, logToast } from "./logger"; const filterCharacter = "\u2588"; +interface RenpyItem { + [key: string]: string | string[]; +} + +interface RenpyFunctions { + config: RenpyItem; + internal: RenpyItem; + renpy: RenpyItem; +} + export class NavigationData { static data: any = {}; - static renpyFunctions: any; + static renpyFunctions: RenpyFunctions; static autoCompleteKeywords: any; static renpyAutoComplete: CompletionItem[]; static configAutoComplete: CompletionItem[]; @@ -25,32 +35,88 @@ export class NavigationData { static isImporting = false; static isCompiling = false; + static makeCompletionItem(name: string, item: string[]): CompletionItem { + const storage = item[0]; + const kind = item[1]; + const args = item[2]; + //const parentClass = item[3]; + const accessKind = item[4]; + const doc = item[5]; + + const completionItem = new CompletionItem(name, undefined); + completionItem.documentation = new MarkdownString(doc); + + if (accessKind === "var") { + completionItem.kind = CompletionItemKind.Field; + } else if (kind === "class" || accessKind === "class") { + completionItem.kind = CompletionItemKind.Class; + } else if (accessKind === "exception") { + completionItem.kind = CompletionItemKind.Issue; + } else if (storage === "basefile") { + completionItem.kind = CompletionItemKind.Field; + } else if (accessKind === "attribute") { + completionItem.kind = CompletionItemKind.Property; + } else if (storage === "audio") { + completionItem.kind = CompletionItemKind.Method; + } else if (accessKind === "ui") { + completionItem.kind = CompletionItemKind.Event; + } else if (kind === "image") { + completionItem.kind = CompletionItemKind.Constant; + } else if (kind === "function" || accessKind === "function") { + completionItem.kind = CompletionItemKind.Function; + } else if (accessKind === "method") { + completionItem.kind = CompletionItemKind.Method; + } else { + console.error("Unhandled kind: " + kind); + } + + // Automatically add parenthesis and trigger hints for functions and methods + if (completionItem.kind === CompletionItemKind.Method || completionItem.kind === CompletionItemKind.Function) { + completionItem.insertText = new SnippetString(`${name}($1)`); + completionItem.command = { command: "editor.action.triggerParameterHints", title: "Parameter Hints" }; + completionItem.detail = `def ${name}(${args})`; + } + + if (storage === "obsolete") { + completionItem.tags = [CompletionItemTag.Deprecated]; + } + return completionItem; + } + static async init(extensionPath: string) { logMessage(LogLevel.Info, `NavigationData init`); - NavigationData.renpyFunctions = data; + NavigationData.renpyFunctions = data as RenpyFunctions; NavigationData.autoCompleteKeywords = kwData; NavigationData.renpyAutoComplete = []; - for (const key in NavigationData.renpyFunctions.renpy) { - if (key.charAt(0) === key.charAt(0).toUpperCase()) { - NavigationData.renpyAutoComplete.push(new CompletionItem(key.substring(6), CompletionItemKind.Class)); - } else { - NavigationData.renpyAutoComplete.push(new CompletionItem(key.substring(6), CompletionItemKind.Method)); + + // for key and value in NavigationData.renpyFunctions.renpy (which is an object) + for (const [key, value] of Object.entries(NavigationData.renpyFunctions.renpy)) { + if (typeof value === "string") { + continue; } + NavigationData.renpyAutoComplete.push(NavigationData.makeCompletionItem(key.substring(6), value)); } NavigationData.configAutoComplete = []; - for (const key in NavigationData.renpyFunctions.config) { - NavigationData.configAutoComplete.push(new CompletionItem(key.substring(7), CompletionItemKind.Property)); + for (const [key, value] of Object.entries(NavigationData.renpyFunctions.config)) { + if (typeof value === "string") { + continue; + } + NavigationData.configAutoComplete.push(NavigationData.makeCompletionItem(key.substring(7), value)); } NavigationData.guiAutoComplete = []; NavigationData.internalAutoComplete = []; - for (const key in NavigationData.renpyFunctions.internal) { - NavigationData.internalAutoComplete.push(new CompletionItem(key, CompletionItemKind.Class)); + for (const [key, value] of Object.entries(NavigationData.renpyFunctions.internal)) { + if (typeof value === "string") { + continue; + } + + NavigationData.internalAutoComplete.push(NavigationData.makeCompletionItem(key, value)); if (key.startsWith("gui.")) { - NavigationData.guiAutoComplete.push(new CompletionItem(key.substring(4), CompletionItemKind.Variable)); + NavigationData.guiAutoComplete.push(NavigationData.makeCompletionItem(key.substring(4), value)); } }