From 71693cc24b54fcff8407318f1e076fb20a13ba64 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Wed, 25 Mar 2026 00:31:29 -0500 Subject: [PATCH] tweak: only spawn lsp servers for files in current instance (or cwd if instance is global) (#19058) --- packages/opencode/src/lsp/index.ts | 6 +++ packages/opencode/test/lsp/index.test.ts | 55 ++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 packages/opencode/test/lsp/index.test.ts diff --git a/packages/opencode/src/lsp/index.ts b/packages/opencode/src/lsp/index.ts index 2eb1ad93e9..41a650afd7 100644 --- a/packages/opencode/src/lsp/index.ts +++ b/packages/opencode/src/lsp/index.ts @@ -177,6 +177,12 @@ export namespace LSP { async function getClients(file: string) { const s = await state() + + // Only spawn LSP clients for files within the instance directory + if (!Instance.containsPath(file)) { + return [] + } + const extension = path.parse(file).ext || file const result: LSPClient.Info[] = [] diff --git a/packages/opencode/test/lsp/index.test.ts b/packages/opencode/test/lsp/index.test.ts new file mode 100644 index 0000000000..7e514e39b1 --- /dev/null +++ b/packages/opencode/test/lsp/index.test.ts @@ -0,0 +1,55 @@ +import { describe, expect, spyOn, test } from "bun:test" +import path from "path" +import * as Lsp from "../../src/lsp/index" +import { LSPServer } from "../../src/lsp/server" +import { Instance } from "../../src/project/instance" +import { tmpdir } from "../fixture/fixture" + +describe("lsp.spawn", () => { + test("does not spawn builtin LSP for files outside instance", async () => { + await using tmp = await tmpdir() + const spy = spyOn(LSPServer.Typescript, "spawn").mockResolvedValue(undefined) + + try { + await Instance.provide({ + directory: tmp.path, + fn: async () => { + await Lsp.LSP.touchFile(path.join(tmp.path, "..", "outside.ts")) + await Lsp.LSP.hover({ + file: path.join(tmp.path, "..", "hover.ts"), + line: 0, + character: 0, + }) + }, + }) + + expect(spy).toHaveBeenCalledTimes(0) + } finally { + spy.mockRestore() + await Instance.disposeAll() + } + }) + + test("would spawn builtin LSP for files inside instance", async () => { + await using tmp = await tmpdir() + const spy = spyOn(LSPServer.Typescript, "spawn").mockResolvedValue(undefined) + + try { + await Instance.provide({ + directory: tmp.path, + fn: async () => { + await Lsp.LSP.hover({ + file: path.join(tmp.path, "src", "inside.ts"), + line: 0, + character: 0, + }) + }, + }) + + expect(spy).toHaveBeenCalledTimes(1) + } finally { + spy.mockRestore() + await Instance.disposeAll() + } + }) +})