From ded7c56fd72efa8ebbbc5fc1ec91ffe0b4a78e3d Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Wed, 26 Feb 2025 05:55:52 -0500 Subject: [PATCH] Add VSCode Project Manager and Recent Workspaces features --- README.md | 13 ++- build.ts | 28 +++-- bun.lockb | Bin 102126 -> 102495 bytes jsr.json | 2 +- package.json | 33 +++++- src/{index.ts => project-manager.ts} | 0 src/recent-workspaces.ts | 163 +++++++++++++++++++++++++++ 7 files changed, 219 insertions(+), 20 deletions(-) rename src/{index.ts => project-manager.ts} (100%) create mode 100644 src/recent-workspaces.ts diff --git a/README.md b/README.md index acb93f3..17ff451 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,15 @@ ## Features -- Open projects stored by project manager extension \ No newline at end of file +- Open projects stored by project manager extension + +## Features + +- Recent VSCode Projects +- Project Manager Projects + +![](https://i.imgur.com/R77kLaH.png) + +## VSCode Recent Projects + +![](https://i.imgur.com/rfzMh9x.png) diff --git a/build.ts b/build.ts index b1bf3e2..38df632 100644 --- a/build.ts +++ b/build.ts @@ -1,20 +1,24 @@ -import { watch } from "fs" -import { join } from "path" -import { refreshTemplateWorkerCommand } from "@kksh/api/dev" -import { $ } from "bun" +import { watch } from "fs"; +import { join } from "path"; +import { refreshTemplateWorkerCommand } from "@kksh/api/dev"; +import { $ } from "bun"; + +const filenames = ["recent-workspaces.ts", "project-manager.ts"]; async function build() { - await $`bun build --minify --target=browser --outdir=./dist ./src/index.ts` - await refreshTemplateWorkerCommand() + for (const filename of filenames) { + await $`bun build --minify --target=browser --outdir=./dist ./src/${filename}`; + } + await refreshTemplateWorkerCommand(); } -const srcDir = join(import.meta.dir, "src") +const srcDir = join(import.meta.dir, "src"); -await build() +await build(); if (Bun.argv.includes("dev")) { - console.log(`Watching ${srcDir} for changes...`) - watch(srcDir, { recursive: true }, async (event, filename) => { - await build() - }) + console.log(`Watching ${srcDir} for changes...`); + watch(srcDir, { recursive: true }, async (event, filename) => { + await build(); + }); } diff --git a/bun.lockb b/bun.lockb index 3067c02ea82ebc5d8555a78ead113fdd7be38818..d8298d44ec74db0344d78a74bd9194da407932cc 100755 GIT binary patch delta 20223 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 L)Sq0yLfHQTsP+CW delta 20121 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

-E0W@&0g=rjRyociO{IZL+_uleS>y4rrr?=4G zcoBtVn0Vy;_fE7A&a|8U7%zZWw<7kJ%@_g5 zE{et#`%Qtar);D_f1*bUySpj7@h2CRH6NO>#>*u(yp?wPTB}oyp-IyQL*ID)gxkci zd$x8C?2MFn3~V&mS5~f2EyfEh3O7n^-|n@;2^uu?(O}f#77h*L-4~-hD;5?X2v`jb z{l=uXtW2VIBz0GYK~pqx7%#tgujQE#_snSrkwbmz5GjPo%FgFB#rPh|m&8$01eK(h z@RaMV)Z;xIG1mp7R^56^`!{bGugZw4nR8%S$Lk-XcKz1dc)3Q()?0r>2Ne9GTB0rh z#l4h(FnIDWG-xBrP@ieqi@P1V*ZTAD9b}W{W4{a~4|&;sC8|B{J0A8{y3@U&_Rb-} zzNpRMc`f!QC(!>(HnFM z3bSqDBW(z!7G{;=?K`Dy@Yon^`%P!d#T1G}hy}lEZRXcctY}mOv`?71uNtss!h;)>?V0vBQV4bj4#B zi&ajPu$jt`4y=nZE|vLJWtFmiCJ$?VQBiT>Xj>L}Js%FvEf}SwPJv+;%GeAkuXtQI z-jtHr;qG(c#Y@9k##%^2pawY+pF8ohNG z#t`gsR9FYr+!RS;Nb&EE9_ieHc~x!hzM^Iw&D8v5KlsUt%Jw3bQh+s4N`IoU8g3uzXY1G8_AyDfOl>H>KFdnkkD$v3O; + +function openWithVSCode(path: string) { + return shell + .hasCommand("code") + .then((hasCommand) => { + if (!hasCommand) { + return toast.error( + "code command not installed to PATH, please install it the 'code' command." + ); + } else { + return shell + .createCommand("code", [path]) + .execute() + .then((res) => { + toast.success(`Opened with VSCode`); + }) + .catch((err) => { + toast.error(`Failed to open with VSCode: ${err}`); + }); + } + }) + .catch((err) => { + toast.error(`${err}`); + }); +} + +class VSCodeProjectManager extends TemplateUiCommand { + async load() { + ui.render(new List.List({ items: [] })); + const platform = await os.platform(); + let fileContent: string | undefined; + if (platform === "macos") { + fileContent = await fs.readTextFile( + "Library/Application Support/Code/User/globalStorage/storage.json", + { baseDir: path.BaseDirectory.Home } + ); + } else if (platform === "windows") { + fileContent = await fs.readTextFile( + "Code/User/globalStorage/storage.json", + { baseDir: path.BaseDirectory.AppData } + ); + } else if (platform === "linux") { + fileContent = await fs.readTextFile( + ".config/Code/User/globalStorage/storage.json", + { baseDir: path.BaseDirectory.Home } + ); + } else { + return toast + .error(`Unsupported platform: ${platform}`) + .then(() => Promise.resolve()); + } + if (!fileContent) { + return toast + .error(`Failed to read Project Manager configuration file`) + .then(() => Promise.resolve()); + } + let jsonContent: Storage | undefined; + try { + jsonContent = JSON.parse(fileContent); + } catch (error) { + return toast.error( + `Failed to parse Project Manager configuration file: ${error}` + ); + } + const parseRes = safeParse(StorageSchema, JSON.parse(fileContent)); + if (!parseRes.success) { + return toast.error( + `Failed to parse Project Manager configuration file: ${flatten< + typeof StorageSchema + >(parseRes.issues)}` + ); + } + let workspaces = Object.keys(parseRes.output.profileAssociations.workspaces) + .filter((w) => w.startsWith("file://")) + .map((w) => w.slice(7)); + workspaces = ( + await Promise.all( + workspaces.map(async (workspace) => ({ + workspace, + exists: await fs.exists(workspace).catch((error) => { + console.error(`Failed to check if ${workspace} exists:`, error); + return false; + }), + })) + ) + ) + .filter(({ exists }) => exists) + .map(({ workspace }) => workspace); + const folderNames = await Promise.all( + workspaces.map(async (workspace) => await path.basename(workspace)) + ); + console.log(folderNames); + const items = folderNames.map((name, idx) => { + return new List.Item({ + title: name, + subTitle: workspaces[idx], + value: workspaces[idx], + icon: new Icon({ + type: IconEnum.Iconify, + value: "ri:folder-open-fill", + }), + }); + }); + return ui.setSearchBarPlaceholder("Search for projects...").then(() => { + return ui.render(new List.List({ items })); + }); + } + + onSearchTermChange(term: string): Promise { + return Promise.resolve(); + } + + async onListItemSelected(value: string): Promise { + log.info(`Selected project: ${value}`); + const platform = await os.platform(); + if (platform === "macos") { + openWithVSCode(value); + // shell.Command.create("code", [value]).execute(); + // shell.executeBashScript(`open -a "Visual Studio Code" "${value}"`) + } else if (platform === "windows") { + openWithVSCode(value); + } else if (platform === "linux") { + openWithVSCode(value); + } else { + toast.error( + `Unsupported platform: ${platform}).then(() => Promise.resolve()` + ); + } + } +} + +expose(new VSCodeProjectManager());