From 6807225c87fbe4310568be4d8e41b57504c260b6 Mon Sep 17 00:00:00 2001 From: David Kincaid Date: Fri, 20 Sep 2024 00:12:36 -0400 Subject: [PATCH 1/6] Fixed lint errors and formatted file --- src/providers/documentation_builder.ts | 228 +++++++++++-------------- 1 file changed, 95 insertions(+), 133 deletions(-) diff --git a/src/providers/documentation_builder.ts b/src/providers/documentation_builder.ts index 85ac8735..b4216fdb 100644 --- a/src/providers/documentation_builder.ts +++ b/src/providers/documentation_builder.ts @@ -3,7 +3,7 @@ import { SymbolKind } from "vscode-languageclient"; import * as Prism from "prismjs"; import * as csharp from "prismjs/components/prism-csharp"; import { marked } from "marked"; -import { GodotNativeSymbol } from "../lsp/gdscript.capabilities"; +import type { GodotNativeSymbol } from "../lsp/gdscript.capabilities"; import { get_extension_uri } from "../utils"; import yabbcode = require("ya-bbcode"); @@ -14,7 +14,7 @@ const parser = new yabbcode(); const wtf = csharp; marked.setOptions({ - highlight: function (code, lang) { + highlight: (code, lang) => { if (lang === "gdscript") { return Prism.highlight(code, GDScriptGrammar, lang); } @@ -69,7 +69,7 @@ export function make_html_content(webview: vscode.Webview, symbol: GodotNativeSy `; } - return /*html*/` + return /*html*/ ` @@ -128,128 +128,94 @@ export function make_symbol_document(symbol: GodotNativeSymbol): string { const ret_type = make_link(parts[2] || "void", undefined); let args = (parts[1] || "").replace( /\:\s([A-z0-9_]+)(\,\s*)?/g, - ": $1$2" + ": $1$2", ); args = args.replace(/\s=\s(.*?)[\,\)]/g, ""); - return `${ret_type} ${with_class ? `${classlink}.` : ""}${element( - "a", - s.name, - { href: `#${s.name}` } - )}( ${args} )`; + return `${ret_type} ${with_class ? `${classlink}.` : ""}${element("a", s.name, { + href: `#${s.name}`, + })}( ${args} )`; } - function make_symbol_elements( - s: GodotNativeSymbol, - with_class = false - ): { index?: string; body: string } { + function make_symbol_elements(s: GodotNativeSymbol, with_class = false): { index?: string; body: string } { switch (s.kind) { case SymbolKind.Property: - case SymbolKind.Variable: - { - // var Control.anchor_left: float - const parts = /\.([A-z_0-9]+)\:\s(.*)$/.exec(s.detail); - if (!parts) { - return; - } - const type = make_link(parts[2], undefined); - const name = element("a", s.name, { href: `#${s.name}` }); - const title = element( - "h4", - `${type} ${with_class ? `${classlink}.` : ""}${s.name}` - ); - const doc = element( - "p", - format_documentation(s.documentation, symbol.native_class) - ); - const div = element("div", title + doc); - return { - index: type + " " + name, - body: div, - }; + case SymbolKind.Variable: { + // var Control.anchor_left: float + const parts = /\.([A-z_0-9]+)\:\s(.*)$/.exec(s.detail); + if (!parts) { + return; } - break; - case SymbolKind.Constant: - { - // const Control.FOCUS_ALL: FocusMode = 2 - // const Control.NOTIFICATION_RESIZED = 40 - const parts = /\.([A-Za-z_0-9]+)(\:\s*)?([A-z0-9_\.]+)?\s*=\s*(.*)$/.exec( - s.detail - ); - if (!parts) { - return; - } - const type = make_link(parts[3] || "int", undefined); - const name = parts[1]; - const value = element("code", parts[4]); - - const title = element( - "p", - `${type} ${with_class ? `${classlink}.` : ""}${name} = ${value}` - ); - const doc = element( - "p", - format_documentation(s.documentation, symbol.native_class) - ); - const div = element("div", title + doc); - return { - body: div, - }; + const type = make_link(parts[2], undefined); + const name = element("a", s.name, { href: `#${s.name}` }); + const title = element("h4", `${type} ${with_class ? `${classlink}.` : ""}${s.name}`); + const doc = element("p", format_documentation(s.documentation, symbol.native_class)); + const div = element("div", title + doc); + return { + index: `${type} ${name}`, + body: div, + }; + } + case SymbolKind.Constant: { + // const Control.FOCUS_ALL: FocusMode = 2 + // const Control.NOTIFICATION_RESIZED = 40 + const parts = /\.([A-Za-z_0-9]+)(\:\s*)?([A-z0-9_\.]+)?\s*=\s*(.*)$/.exec(s.detail); + if (!parts) { + return; } - break; - case SymbolKind.Event: - { - const parts = /\.([A-z0-9]+)\((.*)?\)/.exec(s.detail); - if (!parts) { - return; - } - const args = (parts[2] || "").replace( - /\:\s([A-z0-9_]+)(\,\s*)?/g, - ": $1$2" - ); - const title = element( - "p", - `${with_class ? `signal ${with_class ? `${classlink}.` : ""}` : "" - }${s.name}( ${args} )` - ); - const doc = element( - "p", - format_documentation(s.documentation, symbol.native_class) - ); - const div = element("div", title + doc); - return { - body: div, - }; + const type = make_link(parts[3] || "int", undefined); + const name = parts[1]; + const value = element("code", parts[4]); + + const title = element("p", `${type} ${with_class ? `${classlink}.` : ""}${name} = ${value}`); + const doc = element("p", format_documentation(s.documentation, symbol.native_class)); + const div = element("div", title + doc); + return { + body: div, + }; + } + case SymbolKind.Event: { + const parts = /\.([A-z0-9]+)\((.*)?\)/.exec(s.detail); + if (!parts) { + return; } - break; + const args = (parts[2] || "").replace( + /\:\s([A-z0-9_]+)(\,\s*)?/g, + ": $1$2", + ); + const title = element( + "p", + `${with_class ? `signal ${with_class ? `${classlink}.` : ""}` : ""}${s.name}( ${args} )`, + ); + const doc = element("p", format_documentation(s.documentation, symbol.native_class)); + const div = element("div", title + doc); + return { + body: div, + }; + } case SymbolKind.Method: - case SymbolKind.Function: - { - const signature = make_function_signature(s, with_class); - const title = element("h4", signature); - const doc = element( - "p", - format_documentation(s.documentation, symbol.native_class) - ); - const div = element("div", title + doc); - return { - index: signature, - body: div, - }; - } - break; + case SymbolKind.Function: { + const signature = make_function_signature(s, with_class); + const title = element("h4", signature); + const doc = element("p", format_documentation(s.documentation, symbol.native_class)); + const div = element("div", title + doc); + return { + index: signature, + body: div, + }; + } default: break; } } - if (symbol.kind == SymbolKind.Class) { + if (symbol.kind === SymbolKind.Class) { let doc = element("h2", `Class: ${symbol.name}`); if (symbol.class_info.inherits) { const inherits = make_link(symbol.class_info.inherits, undefined); doc += element("p", `Inherits: ${inherits}`); } - if (symbol.class_info && symbol.class_info.extended_classes) { + if (symbol.class_info?.extended_classes) { let inherited = ""; for (const c of symbol.class_info.extended_classes) { inherited += (inherited ? ", " : " ") + make_link(c, c); @@ -309,18 +275,17 @@ export function make_symbol_document(symbol: GodotNativeSymbol): string { doc += element("script", `var godot_class = "${symbol.native_class}";`); return doc; - } else { - let doc = ""; - const elements = make_symbol_elements(symbol, true); - if (elements.index) { - const symbols: SymbolKind[] = [SymbolKind.Function, SymbolKind.Method]; - if (!symbols.includes(symbol.kind)) { - doc += element("h2", elements.index); - } + } + let doc = ""; + const elements = make_symbol_elements(symbol, true); + if (elements.index) { + const symbols: SymbolKind[] = [SymbolKind.Function, SymbolKind.Method]; + if (!symbols.includes(symbol.kind)) { + doc += element("h2", elements.index); } - doc += element("div", elements.body); - return doc; } + doc += element("div", elements.body); + return doc; } function element( @@ -328,7 +293,7 @@ function element( content: string, props = {}, new_line?: boolean, - indent?: string + indent?: string, ) { let props_str = ""; for (const key in props) { @@ -336,28 +301,26 @@ function element( props_str += ` ${key}="${props[key]}"`; } } - return `${indent || ""}<${tag} ${props_str}>${content}${new_line ? "\n" : "" - }`; + return `${indent || ""}<${tag} ${props_str}>${content}${new_line ? "\n" : ""}`; } function make_link(classname: string, symbol: string) { - if (!symbol || symbol == classname) { + if (!symbol || symbol === classname) { return element("a", classname, { onclick: `inspect('${classname}')`, href: "", }); - } else { - return element("a", `${classname}.${symbol}`, { - onclick: `inspect('${classname}', '${symbol}')`, - href: "", - }); } + return element("a", `${classname}.${symbol}`, { + onclick: `inspect('${classname}', '${symbol}')`, + href: "", + }); } function make_codeblock(code: string, language: string) { const lines = code.split("\n"); const indent = lines[0].match(/^\s*/)[0].length; - code = lines.map(line => line.slice(indent)).join("\n"); + code = lines.map((line) => line.slice(indent)).join("\n"); return marked.parse(`\`\`\`${language}\n${code}\n\`\`\``); } @@ -390,24 +353,21 @@ function format_documentation(bbcode: string, classname: string) { html = html.replaceAll("
", ""); // [param ] - html = html.replaceAll( - /\[param\s+(@?[A-Z_a-z][A-Z_a-z0-9]*?)\]/g, - "$1" - ); + html = html.replaceAll(/\[param\s+(@?[A-Z_a-z][A-Z_a-z0-9]*?)\]/g, "$1"); // [method ] html = html.replaceAll( /\[method\s+(@?[A-Z_a-z][A-Z_a-z0-9]*?)\]/g, - `$1` + `$1`, ); // [] html = html.replaceAll( /\[(\w+)\]/g, - `$1` // eslint-disable-line quotes + `$1`, // eslint-disable-line quotes ); // [method .] html = html.replaceAll( /\[\w+\s+(@?[A-Z_a-z][A-Z_a-z0-9]*?)\.(\w+)\]/g, - `$1.$2` // eslint-disable-line quotes + `$1.$2`, // eslint-disable-line quotes ); return html; @@ -466,8 +426,10 @@ const GDScriptGrammar = { punctuation: /\./, }, }, - keyword: /\b(?:if|elif|else|for|while|break|continue|pass|return|match|func|class|class_name|extends|is|onready|tool|static|export|setget|const|var|as|void|enum|preload|assert|yield|signal|breakpoint|rpc|sync|master|puppet|slave|remotesync|mastersync|puppetsync)\b/, - builtin: /\b(?:PI|TAU|NAN|INF|_|sin|cos|tan|sinh|cosh|tanh|asin|acos|atan|atan2|sqrt|fmod|fposmod|floor|ceil|round|abs|sign|pow|log|exp|is_nan|is_inf|ease|decimals|stepify|lerp|dectime|randomize|randi|randf|rand_range|seed|rand_seed|deg2rad|rad2deg|linear2db|db2linear|max|min|clamp|nearest_po2|weakref|funcref|convert|typeof|type_exists|char|str|print|printt|prints|printerr|printraw|var2str|str2var|var2bytes|bytes2var|range|load|inst2dict|dict2inst|hash|Color8|print_stack|instance_from_id|preload|yield|assert|Vector2|Vector3|Color|Rect2|Array|Basis|Dictionary|Plane|Quat|RID|Rect3|Transform|Transform2D|AABB|String|Color|NodePath|RID|Object|Dictionary|Array|PoolByteArray|PoolIntArray|PoolRealArray|PoolStringArray|PoolVector2Array|PoolVector3Array|PoolColorArray)\b/, + keyword: + /\b(?:if|elif|else|for|while|break|continue|pass|return|match|func|class|class_name|extends|is|onready|tool|static|export|setget|const|var|as|void|enum|preload|assert|yield|signal|breakpoint|rpc|sync|master|puppet|slave|remotesync|mastersync|puppetsync)\b/, + builtin: + /\b(?:PI|TAU|NAN|INF|_|sin|cos|tan|sinh|cosh|tanh|asin|acos|atan|atan2|sqrt|fmod|fposmod|floor|ceil|round|abs|sign|pow|log|exp|is_nan|is_inf|ease|decimals|stepify|lerp|dectime|randomize|randi|randf|rand_range|seed|rand_seed|deg2rad|rad2deg|linear2db|db2linear|max|min|clamp|nearest_po2|weakref|funcref|convert|typeof|type_exists|char|str|print|printt|prints|printerr|printraw|var2str|str2var|var2bytes|bytes2var|range|load|inst2dict|dict2inst|hash|Color8|print_stack|instance_from_id|preload|yield|assert|Vector2|Vector3|Color|Rect2|Array|Basis|Dictionary|Plane|Quat|RID|Rect3|Transform|Transform2D|AABB|String|Color|NodePath|RID|Object|Dictionary|Array|PoolByteArray|PoolIntArray|PoolRealArray|PoolStringArray|PoolVector2Array|PoolVector3Array|PoolColorArray)\b/, boolean: /\b(?:true|false)\b/, number: /(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i, operator: /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/, From 93d327a04f0aa0125dda05a9d5535f936f06ec3e Mon Sep 17 00:00:00 2001 From: David Kincaid Date: Fri, 20 Sep 2024 00:21:40 -0400 Subject: [PATCH 2/6] Fix lint warnings --- src/providers/documentation.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/providers/documentation.ts b/src/providers/documentation.ts index 625400a4..3621a780 100644 --- a/src/providers/documentation.ts +++ b/src/providers/documentation.ts @@ -1,5 +1,5 @@ import * as vscode from "vscode"; -import { +import type { CancellationToken, CustomDocument, CustomDocumentOpenContext, @@ -8,8 +8,8 @@ import { Uri, WebviewPanel, } from "vscode"; -import { NotificationMessage } from "vscode-jsonrpc"; -import { +import type { NotificationMessage } from "vscode-jsonrpc"; +import type { NativeSymbolInspectParams, GodotNativeSymbol, GodotNativeClassInfo, From f78bac7e8dd530003467f71897bce2f9d3bb0a69 Mon Sep 17 00:00:00 2001 From: David Kincaid Date: Fri, 20 Sep 2024 00:21:59 -0400 Subject: [PATCH 3/6] Fix lint warnings --- src/providers/document_link.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/providers/document_link.ts b/src/providers/document_link.ts index bffb0c92..cf183fed 100644 --- a/src/providers/document_link.ts +++ b/src/providers/document_link.ts @@ -2,11 +2,11 @@ import * as vscode from "vscode"; import { Uri, Range, - TextDocument, - CancellationToken, + type TextDocument, + type CancellationToken, DocumentLink, - DocumentLinkProvider, - ExtensionContext, + type DocumentLinkProvider, + type ExtensionContext, } from "vscode"; import { SceneParser } from "../scene_tools"; import { convert_resource_path_to_uri, createLogger } from "../utils"; From e77d40e26f3d465e69c893add78e887cfc69193d Mon Sep 17 00:00:00 2001 From: David Kincaid Date: Fri, 20 Sep 2024 00:49:34 -0400 Subject: [PATCH 4/6] Format document --- src/providers/documentation.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/providers/documentation.ts b/src/providers/documentation.ts index 3621a780..269a3b2a 100644 --- a/src/providers/documentation.ts +++ b/src/providers/documentation.ts @@ -37,9 +37,7 @@ export class GDDocumentationProvider implements CustomReadonlyEditorProvider { }, supportsMultipleEditorsPerDocument: true, }; - context.subscriptions.push( - vscode.window.registerCustomEditorProvider("gddoc", this, options), - ); + context.subscriptions.push(vscode.window.registerCustomEditorProvider("gddoc", this, options)); } public register_capabilities(message: NotificationMessage) { @@ -63,23 +61,28 @@ export class GDDocumentationProvider implements CustomReadonlyEditorProvider { } public async list_native_classes() { - const classname = await vscode.window.showQuickPick( - [...this.classInfo.keys()].sort(), - { - placeHolder: "Type godot class name here", - canPickMany: false, - } - ); + const classname = await vscode.window.showQuickPick([...this.classInfo.keys()].sort(), { + placeHolder: "Type godot class name here", + canPickMany: false, + }); if (classname) { vscode.commands.executeCommand("vscode.open", make_docs_uri(classname)); } } - public openCustomDocument(uri: Uri, openContext: CustomDocumentOpenContext, token: CancellationToken): CustomDocument { - return { uri: uri, dispose: () => { } }; + public openCustomDocument( + uri: Uri, + openContext: CustomDocumentOpenContext, + token: CancellationToken, + ): CustomDocument { + return { uri: uri, dispose: () => {} }; } - public async resolveCustomEditor(document: CustomDocument, panel: WebviewPanel, token: CancellationToken): Promise { + public async resolveCustomEditor( + document: CustomDocument, + panel: WebviewPanel, + token: CancellationToken, + ): Promise { const className = document.uri.path.split(".")[0]; const target = document.uri.fragment; let symbol: GodotNativeSymbol = null; @@ -89,7 +92,7 @@ export class GDDocumentationProvider implements CustomReadonlyEditorProvider { }; while (!this.ready) { - await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise((resolve) => setTimeout(resolve, 100)); } symbol = this.symbolDb.get(className); @@ -111,7 +114,7 @@ export class GDDocumentationProvider implements CustomReadonlyEditorProvider { } panel.webview.html = this.htmlDb.get(className); panel.iconPath = get_extension_uri("resources/godot_icon.svg"); - panel.webview.onDidReceiveMessage(msg => { + panel.webview.onDidReceiveMessage((msg) => { if (msg.type === "INSPECT_NATIVE_SYMBOL") { const uri = make_docs_uri(msg.data.native_class, msg.data.symbol_name); vscode.commands.executeCommand("vscode.open", uri); From 5a10f28e5a03841c920949cd75aaf3727ff14ae1 Mon Sep 17 00:00:00 2001 From: David Kincaid Date: Fri, 20 Sep 2024 00:50:55 -0400 Subject: [PATCH 5/6] Add documentation.pageScale mechanism --- package.json | 7 +++++++ src/providers/documentation.ts | 7 +++++-- src/providers/documentation_builder.ts | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e6d1fcbc..07066fdd 100644 --- a/package.json +++ b/package.json @@ -251,6 +251,13 @@ "type": "object", "title": "Godot Tools", "properties": { + "godotTools.documentation.pageScale": { + "type": "integer", + "default": 100, + "minimum": 50, + "maximum": 200, + "description": "Scale factor (%) to apply to the Godot documentation viewer." + }, "godotTools.editorPath.godot3": { "type": "string", "default": "godot3", diff --git a/src/providers/documentation.ts b/src/providers/documentation.ts index 269a3b2a..8254a3ae 100644 --- a/src/providers/documentation.ts +++ b/src/providers/documentation.ts @@ -16,7 +16,7 @@ import type { GodotCapabilities, } from "../lsp/gdscript.capabilities"; import { make_html_content } from "./documentation_builder"; -import { createLogger, get_extension_uri, make_docs_uri } from "../utils"; +import { createLogger, get_configuration, get_extension_uri, make_docs_uri } from "../utils"; import { globals } from "../extension"; const log = createLogger("providers.docs"); @@ -112,7 +112,10 @@ export class GDDocumentationProvider implements CustomReadonlyEditorProvider { if (!this.htmlDb.has(className)) { this.htmlDb.set(className, make_html_content(panel.webview, symbol, target)); } - panel.webview.html = this.htmlDb.get(className); + + const scaleFactor = get_configuration("documentation.pageScale"); + + panel.webview.html = this.htmlDb.get(className).replaceAll("scaleFactor", scaleFactor); panel.iconPath = get_extension_uri("resources/godot_icon.svg"); panel.webview.onDidReceiveMessage((msg) => { if (msg.type === "INSPECT_NATIVE_SYMBOL") { diff --git a/src/providers/documentation_builder.ts b/src/providers/documentation_builder.ts index b4216fdb..3f823e6f 100644 --- a/src/providers/documentation_builder.ts +++ b/src/providers/documentation_builder.ts @@ -78,7 +78,7 @@ export function make_html_content(webview: vscode.Webview, symbol: GodotNativeSy ${symbol.name} - +
${make_symbol_document(symbol)}
From 832c1ea0f039acd44f91df7fa4991dac4d97d602 Mon Sep 17 00:00:00 2001 From: David Kincaid Date: Fri, 20 Sep 2024 01:28:37 -0400 Subject: [PATCH 6/6] Fix issue with div of map() function catching the minimap style --- media/docs.css | 2 +- src/providers/documentation_builder.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/media/docs.css b/media/docs.css index c73718b2..2e2d1a8c 100644 --- a/media/docs.css +++ b/media/docs.css @@ -6,7 +6,7 @@ a { text-decoration: none; } -#map { +#minimap { position: fixed; top: 0; right: 0; diff --git a/src/providers/documentation_builder.ts b/src/providers/documentation_builder.ts index 3f823e6f..9d7d3f26 100644 --- a/src/providers/documentation_builder.ts +++ b/src/providers/documentation_builder.ts @@ -83,11 +83,11 @@ export function make_html_content(webview: vscode.Webview, symbol: GodotNativeSy ${make_symbol_document(symbol)} - +