UNPKG

equicord-companion

Version:

Equicord Companion is a vscode extension to test Equicord patches & webpack finds right from the comfort of your IDE

363 lines (328 loc) 14 kB
import { onEditCallback, onOpenCallback } from "@ast/vencord/diagnostics"; import { I18nHover } from "@ast/vencord/hover"; import { PatchCodeLensProvider, PluginDefCodeLensProvider, WebpackCodeLensProvider } from "@ast/vencord/lenses"; import { PartialModuleJumpCodeLensProvider } from "@ast/webpack/lenses"; import { DefinitionProvider, ReferenceProvider } from "@ast/webpack/lsp"; import { outputChannel } from "@modules/logging"; import { PatchHelper } from "@modules/PatchHelper"; import { handleDiffPayload, handleExtractPayload, moduleCache, sendAndGetData, startWebSocketServer, stopWebSocketServer } from "@server"; import { treeDataProvider } from "@sidebar"; import { SourcePatch } from "@type/ast"; import { Discriminate } from "@type/server"; import { DisablePluginData, FindData, OutgoingMessage, PatchData } from "@type/server/send"; import { startReporter } from "./reporter"; import { commands, ExtensionContext, languages, QuickPickItem, TextDocument, Uri, window as vscWindow, window, workspace } from "vscode"; export let extensionUri: Uri; export let extensionPath: string; export function activate(context: ExtensionContext) { extensionUri = context.extensionUri; extensionPath = context.extensionPath; startWebSocketServer(); context.subscriptions.push( window.registerTreeDataProvider("equicordSettings", new treeDataProvider()), workspace.onDidChangeTextDocument(onEditCallback), workspace.onDidOpenTextDocument(onOpenCallback), workspace.onDidCloseTextDocument(PatchHelper.onCloseDocument), workspace.onDidChangeTextDocument(PatchHelper.changeDocument), window.onDidChangeActiveTextEditor(PatchHelper.changeActiveEditor), window.tabGroups.onDidChangeTabs(PatchHelper.onTabClose), languages.registerCodeLensProvider( { pattern: "**/{plugins,userplugins,equicordplugins,plugins/_*,equicordplugins/_*}/{*.ts,*.tsx,**/index.ts,**/index.tsx}" }, new PluginDefCodeLensProvider(), ), languages.registerCodeLensProvider( { pattern: "**/{plugins,userplugins,equicordplugins,plugins/_*,equicordplugins/_*}/{*.ts,*.tsx,**/index.ts,**/index.tsx}" }, new PatchCodeLensProvider(), ), languages.registerDefinitionProvider({ language: "javascript" }, new DefinitionProvider()), languages.registerReferenceProvider({ language: "javascript" }, new ReferenceProvider()), languages.registerCodeLensProvider({ language: "typescript" }, WebpackCodeLensProvider), languages.registerCodeLensProvider({ language: "typescriptreact" }, WebpackCodeLensProvider), languages.registerCodeLensProvider({ language: "javascript" }, new PartialModuleJumpCodeLensProvider()), languages.registerHoverProvider({ language: "typescript" }, new I18nHover()), languages.registerHoverProvider({ language: "typescriptreact" }, new I18nHover()), workspace.registerTextDocumentContentProvider("equicord-patchhelper", PatchHelper), workspace.registerTextDocumentContentProvider("equicord-companion", { provideTextDocumentContent(uri) { // FIXME: full uri shows up in title bar const newLocal = Buffer.from(uri.path.substring(1, uri.path.lastIndexOf("/")), "base64url"); return newLocal.toString(); }, }), commands.registerCommand("equicord-companion.openPatchHelper", async (doc: TextDocument, patch: SourcePatch) => { if (!doc) { outputChannel.warn("Could not find source document"); window.showErrorMessage("Could not find source document"); return; } const helper = await PatchHelper.create(doc, patch); helper.openModuleWindow(); }), commands.registerCommand("equicord-companion.runReporter", startReporter), commands.registerCommand("equicord-companion.diffModule", async (args) => { if (args) { try { const r = await sendAndGetData<"diff">({ type: "diff", data: { extractType: "id", idOrSearch: args, }, }); handleDiffPayload(r); } catch (e) { outputChannel.error(String(e)); window.showErrorMessage(String(e)); } return; } // FIXME: refactor to generic quicpick class with these features const quickPick = window.createQuickPick(); quickPick.placeholder = "module ID"; quickPick.canSelectMany = false; const items: QuickPickItem[] = [ { label: "", alwaysShow: false, }, { label: "", kind: -1, }, ...moduleCache.map((m) => ({ label: m })), ]; quickPick.items = items; quickPick.onDidChangeValue(() => { if (!moduleCache.includes(quickPick.value)) { items[0].label = quickPick.value; items[0].alwaysShow = true; } else { items[0].alwaysShow = false; } quickPick.items = items; }); quickPick.show(); quickPick.onDidAccept(async () => { const modId = quickPick.value; quickPick.dispose(); if (!modId || isNaN(+modId)) return vscWindow.showErrorMessage("No Module ID provided"); try { const r = await sendAndGetData<"diff">({ type: "diff", data: { extractType: "id", idOrSearch: +modId, }, }); handleDiffPayload(r); } catch (error) { outputChannel.error(String(error)); vscWindow.showErrorMessage(String(error)); } }); }), commands.registerCommand("equicord-companion.diffModuleSearch", async (args: string, findType: "string" | "regex") => { if (args) { try { const r = await sendAndGetData<"diff">({ type: "diff", data: { extractType: "search", findType, idOrSearch: args, }, }); handleDiffPayload(r); } catch (e) { outputChannel.error(String(e)); window.showErrorMessage(String(e)); } return; } const input = await window.showInputBox(); if (!input) { outputChannel.warn("No Input Provided"); return window.showErrorMessage("No Input Provided"); } try { const r = await sendAndGetData<"diff">({ type: "diff", data: { extractType: "search", findType: "string", idOrSearch: input, }, }); handleDiffPayload(r); } catch (e) { outputChannel.error(String(e)); vscWindow.showErrorMessage(String(e)); } }), commands.registerCommand("equicord-companion.extractFind", async (args: Discriminate<OutgoingMessage, "extract">) => { if (!args) { outputChannel.warn("No Data Provided"); vscWindow.showErrorMessage("No Data Provided"); return; } try { const r = await sendAndGetData<"extract">(args); handleExtractPayload(r); } catch (e) { outputChannel.error(String(e)); vscWindow.showErrorMessage(String(e)); } }), commands.registerCommand("equicord-companion.extract", async (args: number) => { if (args) { try { const r = await sendAndGetData<"extract">({ type: "extract", data: { extractType: "id", idOrSearch: args, usePatched: null, }, }); handleExtractPayload(r); } catch (e) { outputChannel.error(String(e)); window.showErrorMessage(String(e)); } return; } const quickPick = window.createQuickPick(); quickPick.placeholder = "module ID"; quickPick.canSelectMany = false; const items: QuickPickItem[] = [ { label: "", alwaysShow: false, }, { label: "", kind: -1, }, ...moduleCache.map((m) => { return { label: m }; }), ]; quickPick.items = items; quickPick.onDidChangeValue(() => { if (!moduleCache.includes(quickPick.value)) { items[0].label = quickPick.value; items[0].alwaysShow = true; } else { items[0].alwaysShow = false; } quickPick.items = items; }); quickPick.show(); quickPick.onDidAccept(async () => { const modId = quickPick.value; quickPick.dispose(); if (!modId || isNaN(+modId)) return vscWindow.showErrorMessage("No Module ID provided"); try { const r = await sendAndGetData<"extract">({ type: "extract", data: { extractType: "id", idOrSearch: +modId, usePatched: null, }, }); handleExtractPayload(r); } catch (e) { outputChannel.error(String(e)); vscWindow.showErrorMessage(String(e)); } }); }), commands.registerCommand("equicord-companion.extractSearch", async (args: string, findType: "string" | "regex") => { if (args) { try { const r = await sendAndGetData<"extract">({ type: "extract", data: { extractType: "search", findType, idOrSearch: args, usePatched: null, }, }); handleExtractPayload(r); } catch (e) { outputChannel.error(String(e)); window.showErrorMessage(String(e)); } return; } const input = await window.showInputBox(); if (!input) return window.showErrorMessage("No Input Provided"); try { const r = await sendAndGetData<"extract">({ type: "extract", data: { extractType: "search", findType: "string", idOrSearch: input, usePatched: null, }, }); handleExtractPayload(r); } catch (e) { outputChannel.error(String(e)); vscWindow.showErrorMessage(String(e)); } }), commands.registerCommand("equicord-companion.disablePlugin", async (data: DisablePluginData) => { try { if (!data) throw new Error("No args passed."); await sendAndGetData({ type: "disable", data, }); } catch (e) { outputChannel.error(String(e)); vscWindow.showErrorMessage(String(e)); } }), commands.registerCommand("equicord-companion.testPatch", async (patch: PatchData) => { try { await sendAndGetData({ type: "testPatch", data: patch, }); vscWindow.showInformationMessage("Patch OK!"); } catch (e) { outputChannel.info(`Patch failed: ${e}`); vscWindow.showErrorMessage(`Patch failed: ${e}`); } }), commands.registerCommand("equicord-companion.testFind", async (find: FindData) => { try { await sendAndGetData({ type: "testFind", data: find, }); vscWindow.showInformationMessage("Find OK!"); } catch (e) { outputChannel.info(`Find bad: ${e}`); vscWindow.showErrorMessage(`Find bad: ${e}`); } }), ); if (window.activeTextEditor) { onOpenCallback(window.activeTextEditor.document); } } export function deactivate() { stopWebSocketServer(); } export { outputChannel, };