642 lines · 20.7 KB · TypeScript
RawDownload
import * as NodeServices from "@effect/platform-node/NodeServices";import { assert, it } from "@effect/vitest";import { assertSuccess } from "@effect/vitest/utils";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Path from "effect/Path";import * as Random from "effect/Random"; import {  isCommandAvailable,  launchDetached,  resolveAvailableEditors,  resolveEditorLaunch,} from "./open.ts"; it.layer(NodeServices.layer)("resolveEditorLaunch", (it) => {  it.effect("returns commands for command-based editors", () =>    Effect.gen(function* () {      const antigravityLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "antigravity" },        "darwin",        { PATH: "" },      );      assert.deepEqual(antigravityLaunch, {        command: "agy",        args: ["/tmp/workspace"],      });       const cursorLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "cursor" },        "darwin",        { PATH: "" },      );      assert.deepEqual(cursorLaunch, {        command: "cursor",        args: ["/tmp/workspace"],      });       const traeLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "trae" },        "darwin",      );      assert.deepEqual(traeLaunch, {        command: "trae",        args: ["/tmp/workspace"],      });       const kiroLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "kiro" },        "darwin",        { PATH: "" },      );      assert.deepEqual(kiroLaunch, {        command: "kiro",        args: ["ide", "/tmp/workspace"],      });       const vscodeLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "vscode" },        "darwin",        { PATH: "" },      );      assert.deepEqual(vscodeLaunch, {        command: "code",        args: ["/tmp/workspace"],      });       const vscodeInsidersLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "vscode-insiders" },        "darwin",      );      assert.deepEqual(vscodeInsidersLaunch, {        command: "code-insiders",        args: ["/tmp/workspace"],      });       const vscodiumLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "vscodium" },        "darwin",      );      assert.deepEqual(vscodiumLaunch, {        command: "codium",        args: ["/tmp/workspace"],      });       const zedLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "zed" },        "darwin",        { PATH: "" },      );      assert.deepEqual(zedLaunch, {        command: "zed",        args: ["/tmp/workspace"],      });       const ideaLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "idea" },        "darwin",      );      assert.deepEqual(ideaLaunch, {        command: "idea",        args: ["/tmp/workspace"],      });       const aquaLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "aqua" },        "darwin",      );      assert.deepEqual(aquaLaunch, {        command: "aqua",        args: ["/tmp/workspace"],      });       const clionLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "clion" },        "darwin",      );      assert.deepEqual(clionLaunch, {        command: "clion",        args: ["/tmp/workspace"],      });       const datagripLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "datagrip" },        "darwin",      );      assert.deepEqual(datagripLaunch, {        command: "datagrip",        args: ["/tmp/workspace"],      });       const dataspellLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "dataspell" },        "darwin",      );      assert.deepEqual(dataspellLaunch, {        command: "dataspell",        args: ["/tmp/workspace"],      });       const golandLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "goland" },        "darwin",      );      assert.deepEqual(golandLaunch, {        command: "goland",        args: ["/tmp/workspace"],      });       const phpstormLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "phpstorm" },        "darwin",      );      assert.deepEqual(phpstormLaunch, {        command: "phpstorm",        args: ["/tmp/workspace"],      });       const pycharmLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "pycharm" },        "darwin",      );      assert.deepEqual(pycharmLaunch, {        command: "pycharm",        args: ["/tmp/workspace"],      });       const riderLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "rider" },        "darwin",      );      assert.deepEqual(riderLaunch, {        command: "rider",        args: ["/tmp/workspace"],      });       const rubymineLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "rubymine" },        "darwin",      );      assert.deepEqual(rubymineLaunch, {        command: "rubymine",        args: ["/tmp/workspace"],      });       const rustroverLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "rustrover" },        "darwin",      );      assert.deepEqual(rustroverLaunch, {        command: "rustrover",        args: ["/tmp/workspace"],      });       const webstormLaunch = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "webstorm" },        "darwin",      );      assert.deepEqual(webstormLaunch, {        command: "webstorm",        args: ["/tmp/workspace"],      });    }),  );   it.effect("applies launch-style-specific navigation arguments", () =>    Effect.gen(function* () {      const lineOnly = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/AGENTS.md:48", editor: "cursor" },        "darwin",        { PATH: "" },      );      assert.deepEqual(lineOnly, {        command: "cursor",        args: ["--goto", "/tmp/workspace/AGENTS.md:48"],      });       const lineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "cursor" },        "darwin",        { PATH: "" },      );      assert.deepEqual(lineAndColumn, {        command: "cursor",        args: ["--goto", "/tmp/workspace/src/open.ts:71:5"],      });       const traeLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "trae" },        "darwin",      );      assert.deepEqual(traeLineAndColumn, {        command: "trae",        args: ["--goto", "/tmp/workspace/src/open.ts:71:5"],      });       const kiroLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "kiro" },        "darwin",        { PATH: "" },      );      assert.deepEqual(kiroLineAndColumn, {        command: "kiro",        args: ["ide", "--goto", "/tmp/workspace/src/open.ts:71:5"],      });       const vscodeLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "vscode" },        "darwin",        { PATH: "" },      );      assert.deepEqual(vscodeLineAndColumn, {        command: "code",        args: ["--goto", "/tmp/workspace/src/open.ts:71:5"],      });       const vscodeInsidersLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "vscode-insiders" },        "darwin",      );      assert.deepEqual(vscodeInsidersLineAndColumn, {        command: "code-insiders",        args: ["--goto", "/tmp/workspace/src/open.ts:71:5"],      });       const vscodiumLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "vscodium" },        "darwin",      );      assert.deepEqual(vscodiumLineAndColumn, {        command: "codium",        args: ["--goto", "/tmp/workspace/src/open.ts:71:5"],      });       const zedLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "zed" },        "darwin",        { PATH: "" },      );      assert.deepEqual(zedLineAndColumn, {        command: "zed",        args: ["/tmp/workspace/src/open.ts:71:5"],      });       const zedLineOnly = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/AGENTS.md:48", editor: "zed" },        "darwin",        { PATH: "" },      );      assert.deepEqual(zedLineOnly, {        command: "zed",        args: ["/tmp/workspace/AGENTS.md:48"],      });       const ideaLineOnly = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/AGENTS.md:48", editor: "idea" },        "darwin",      );      assert.deepEqual(ideaLineOnly, {        command: "idea",        args: ["--line", "48", "/tmp/workspace/AGENTS.md"],      });       const ideaLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "idea" },        "darwin",      );      assert.deepEqual(ideaLineAndColumn, {        command: "idea",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const aquaLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "aqua" },        "darwin",      );      assert.deepEqual(aquaLineAndColumn, {        command: "aqua",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const clionLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "clion" },        "darwin",      );      assert.deepEqual(clionLineAndColumn, {        command: "clion",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const datagripLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "datagrip" },        "darwin",      );      assert.deepEqual(datagripLineAndColumn, {        command: "datagrip",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const dataspellLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "dataspell" },        "darwin",      );      assert.deepEqual(dataspellLineAndColumn, {        command: "dataspell",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const golandLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "goland" },        "darwin",      );      assert.deepEqual(golandLineAndColumn, {        command: "goland",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const phpstormLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "phpstorm" },        "darwin",      );      assert.deepEqual(phpstormLineAndColumn, {        command: "phpstorm",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const pycharmLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "pycharm" },        "darwin",      );      assert.deepEqual(pycharmLineAndColumn, {        command: "pycharm",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const riderLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "rider" },        "darwin",      );      assert.deepEqual(riderLineAndColumn, {        command: "rider",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const rubymineLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "rubymine" },        "darwin",      );      assert.deepEqual(rubymineLineAndColumn, {        command: "rubymine",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const rustroverLineAndColumn = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "rustrover" },        "darwin",      );      assert.deepEqual(rustroverLineAndColumn, {        command: "rustrover",        args: ["--line", "71", "--column", "5", "/tmp/workspace/src/open.ts"],      });       const webstormLineOnly = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace/AGENTS.md:48", editor: "webstorm" },        "darwin",      );      assert.deepEqual(webstormLineOnly, {        command: "webstorm",        args: ["--line", "48", "/tmp/workspace/AGENTS.md"],      });    }),  );   it.effect("falls back to zeditor when zed is not installed", () =>    Effect.gen(function* () {      const fs = yield* FileSystem.FileSystem;      const path = yield* Path.Path;      const dir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-open-test-" });      yield* fs.writeFileString(path.join(dir, "zeditor"), "#!/bin/sh\nexit 0\n");      yield* fs.chmod(path.join(dir, "zeditor"), 0o755);       const result = yield* resolveEditorLaunch({ cwd: "/tmp/workspace", editor: "zed" }, "linux", {        PATH: dir,      });       assert.deepEqual(result, {        command: "zeditor",        args: ["/tmp/workspace"],      });    }),  );   it.effect("falls back to the primary command when no alias is installed", () =>    Effect.gen(function* () {      const result = yield* resolveEditorLaunch({ cwd: "/tmp/workspace", editor: "zed" }, "linux", {        PATH: "",      });      assert.deepEqual(result, {        command: "zed",        args: ["/tmp/workspace"],      });    }),  );   it.effect("maps file-manager editor to OS open commands", () =>    Effect.gen(function* () {      const launch1 = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "file-manager" },        "darwin",        { PATH: "" },      );      assert.deepEqual(launch1, {        command: "open",        args: ["/tmp/workspace"],      });       const launch2 = yield* resolveEditorLaunch(        { cwd: "C:\\workspace", editor: "file-manager" },        "win32",        { PATH: "" },      );      assert.deepEqual(launch2, {        command: "explorer",        args: ["C:\\workspace"],      });       const launch3 = yield* resolveEditorLaunch(        { cwd: "/tmp/workspace", editor: "file-manager" },        "linux",        { PATH: "" },      );      assert.deepEqual(launch3, {        command: "xdg-open",        args: ["/tmp/workspace"],      });    }),  );}); it.layer(NodeServices.layer)("launchDetached", (it) => {  it.effect("resolves when command can be spawned", () =>    Effect.gen(function* () {      const result = yield* launchDetached({        command: process.execPath,        args: ["-e", "process.exit(0)"],      }).pipe(Effect.result);      assertSuccess(result, undefined);    }),  );   it.effect("rejects when command does not exist", () =>    Effect.gen(function* () {      const result = yield* launchDetached({        command: `t3code-no-such-command-${yield* Random.nextUUIDv4}`,        args: [],      }).pipe(Effect.result);      assert.equal(result._tag, "Failure");    }),  );});

Lines 1–500 of 642.