From 81ebf56cf1eaea4ed5a2b4f8bb50db53ac4cdfb0 Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Tue, 18 Nov 2025 17:44:34 -0600 Subject: [PATCH] feat: add top level lsp: false and formatter: false to allow disabling all formatters or lsps at once --- packages/opencode/src/config/config.ts | 55 +++++++++++++++----------- packages/opencode/src/format/index.ts | 8 ++++ packages/opencode/src/lsp/index.ts | 13 +++++- packages/sdk/js/src/gen/types.gen.ts | 50 ++++++++++++----------- 4 files changed, 78 insertions(+), 48 deletions(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index d9c453038..c40a910e0 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -542,36 +542,43 @@ export namespace Config { .describe("Custom provider configurations and model overrides"), mcp: z.record(z.string(), Mcp).optional().describe("MCP (Model Context Protocol) server configurations"), formatter: z - .record( - z.string(), - z.object({ - disabled: z.boolean().optional(), - command: z.array(z.string()).optional(), - environment: z.record(z.string(), z.string()).optional(), - extensions: z.array(z.string()).optional(), - }), - ) + .union([ + z.literal(false), + z.record( + z.string(), + z.object({ + disabled: z.boolean().optional(), + command: z.array(z.string()).optional(), + environment: z.record(z.string(), z.string()).optional(), + extensions: z.array(z.string()).optional(), + }), + ), + ]) .optional(), lsp: z - .record( - z.string(), - z.union([ - z.object({ - disabled: z.literal(true), - }), - z.object({ - command: z.array(z.string()), - extensions: z.array(z.string()).optional(), - disabled: z.boolean().optional(), - env: z.record(z.string(), z.string()).optional(), - initialization: z.record(z.string(), z.any()).optional(), - }), - ]), - ) + .union([ + z.literal(false), + z.record( + z.string(), + z.union([ + z.object({ + disabled: z.literal(true), + }), + z.object({ + command: z.array(z.string()), + extensions: z.array(z.string()).optional(), + disabled: z.boolean().optional(), + env: z.record(z.string(), z.string()).optional(), + initialization: z.record(z.string(), z.any()).optional(), + }), + ]), + ), + ]) .optional() .refine( (data) => { if (!data) return true + if (typeof data === "boolean") return true const serverIds = new Set(Object.values(LSPServer).map((s) => s.id)) return Object.entries(data).every(([id, config]) => { diff --git a/packages/opencode/src/format/index.ts b/packages/opencode/src/format/index.ts index 9cb4545b0..bab758030 100644 --- a/packages/opencode/src/format/index.ts +++ b/packages/opencode/src/format/index.ts @@ -28,6 +28,14 @@ export namespace Format { const cfg = await Config.get() const formatters: Record = {} + if (cfg.formatter === false) { + log.info("all formatters are disabled") + return { + enabled, + formatters, + } + } + for (const item of Object.values(Formatter)) { formatters[item.name] = item } diff --git a/packages/opencode/src/lsp/index.ts b/packages/opencode/src/lsp/index.ts index 6b5379742..6c082d0d7 100644 --- a/packages/opencode/src/lsp/index.ts +++ b/packages/opencode/src/lsp/index.ts @@ -62,10 +62,21 @@ export namespace LSP { async () => { const clients: LSPClient.Info[] = [] const servers: Record = {} + const cfg = await Config.get() + + if (cfg.lsp === false) { + log.info("all LSPs are disabled") + return { + broken: new Set(), + servers, + clients, + spawning: new Map>(), + } + } + for (const server of Object.values(LSPServer)) { servers[server.id] = server } - const cfg = await Config.get() for (const [name, item] of Object.entries(cfg.lsp ?? {})) { const existing = servers[name] if (item.disabled) { diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index c63081f82..d9414d393 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -1117,33 +1117,37 @@ export type Config = { mcp?: { [key: string]: McpLocalConfig | McpRemoteConfig } - formatter?: { - [key: string]: { - disabled?: boolean - command?: Array - environment?: { - [key: string]: string - } - extensions?: Array - } - } - lsp?: { - [key: string]: - | { - disabled: true - } - | { - command: Array - extensions?: Array + formatter?: + | false + | { + [key: string]: { disabled?: boolean - env?: { + command?: Array + environment?: { [key: string]: string } - initialization?: { - [key: string]: unknown - } + extensions?: Array } - } + } + lsp?: + | false + | { + [key: string]: + | { + disabled: true + } + | { + command: Array + extensions?: Array + disabled?: boolean + env?: { + [key: string]: string + } + initialization?: { + [key: string]: unknown + } + } + } /** * Additional instruction files or patterns to include */