summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-08-01 14:51:58 -0400
committerDax Raad <[email protected]>2025-08-01 14:52:10 -0400
commit98b6bb218b45b3c2a8a7a1a69e2e715a21321de2 (patch)
treee75029a03bcacdb8f7d79177b8065e17df86cd6f
parent5592ce8eaf93ab8a45544d7809b24ab88a90f2cc (diff)
downloadopencode-98b6bb218b45b3c2a8a7a1a69e2e715a21321de2.tar.gz
opencode-98b6bb218b45b3c2a8a7a1a69e2e715a21321de2.zip
configurable lsp
-rw-r--r--packages/opencode/src/config/config.ts17
-rw-r--r--packages/opencode/src/lsp/index.ts29
-rw-r--r--packages/web/src/content/docs/docs/lsp.mdx79
-rw-r--r--packages/web/src/pages/s/[id].astro7
4 files changed, 131 insertions, 1 deletions
diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts
index 3d933a152..acce3b61b 100644
--- a/packages/opencode/src/config/config.ts
+++ b/packages/opencode/src/config/config.ts
@@ -289,6 +289,23 @@ export namespace Config {
}),
)
.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(),
+ }),
+ ]),
+ )
+ .optional(),
instructions: z.array(z.string()).optional().describe("Additional instruction files or patterns to include"),
layout: Layout.optional().describe("@deprecated Always uses stretch layout."),
permission: z
diff --git a/packages/opencode/src/lsp/index.ts b/packages/opencode/src/lsp/index.ts
index 8f6c1c9cb..09e3c55cd 100644
--- a/packages/opencode/src/lsp/index.ts
+++ b/packages/opencode/src/lsp/index.ts
@@ -4,6 +4,8 @@ import { LSPClient } from "./client"
import path from "path"
import { LSPServer } from "./server"
import { z } from "zod"
+import { Config } from "../config/config"
+import { spawn } from "child_process"
export namespace LSP {
const log = Log.create({ service: "lsp" })
@@ -55,6 +57,31 @@ export namespace LSP {
"lsp",
async () => {
const clients: LSPClient.Info[] = []
+ const servers: Record<string, LSPServer.Info> = LSPServer
+ const cfg = await Config.get()
+ for (const [name, item] of Object.entries(cfg.lsp ?? {})) {
+ const existing = servers[name]
+ if (item.disabled) {
+ delete servers[name]
+ continue
+ }
+ servers[name] = {
+ ...existing,
+ extensions: item.extensions ?? existing.extensions,
+ spawn: async (_app, root) => {
+ return {
+ process: spawn(item.command[0], item.command.slice(1), {
+ cwd: root,
+ env: {
+ ...process.env,
+ ...item.env,
+ },
+ }),
+ initialization: item.initialization,
+ }
+ },
+ }
+ }
return {
broken: new Set<string>(),
clients,
@@ -76,7 +103,7 @@ export namespace LSP {
const extension = path.parse(file).ext
const result: LSPClient.Info[] = []
for (const server of Object.values(LSPServer)) {
- if (!server.extensions.includes(extension)) continue
+ if (server.extensions.length && !server.extensions.includes(extension)) continue
const root = await server.root(file, App.info())
if (!root) continue
if (s.broken.has(root + server.id)) continue
diff --git a/packages/web/src/content/docs/docs/lsp.mdx b/packages/web/src/content/docs/docs/lsp.mdx
new file mode 100644
index 000000000..791f4f285
--- /dev/null
+++ b/packages/web/src/content/docs/docs/lsp.mdx
@@ -0,0 +1,79 @@
+---
+title: LSP Servers
+description: Language Server Protocol integration with opencode
+---
+
+opencode integrates with Language Server Protocol (LSP) to enhance how the LLM interacts with your codebase. LSP servers provide intelligent code analysis and editing capabilities for different programming languages.
+
+## Built-in LSP Servers
+
+opencode comes with several built-in LSP servers for popular languages:
+
+| LSP Server | Languages/Extensions | Requirements |
+| ---------- | -------------------------------------------- | ----------------------------------- |
+| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
+| gopls | .go | `go` command available |
+| ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available |
+| pyright | .py, .pyi | `pyright` dependency installed |
+| elixir-ls | .ex, .exs | `elixir` command available |
+| zls | .zig, .zon | `zig` command available |
+| csharp | .cs | `.NET SDK` installed |
+
+LSP servers are automatically enabled when their requirements are met in your project environment.
+
+## Configuration
+
+You can customize LSP servers through the `lsp` section in your `opencode.json` configuration file.
+
+### Disabling LSP Servers
+
+To disable a specific LSP server, set its configuration to `{ "disabled": true }`:
+
+```json title="opencode.json"
+{
+ "$schema": "https://opencode.ai/config.json",
+ "lsp": {
+ "typescript": {
+ "disabled": true
+ }
+ }
+}
+```
+
+### Custom LSP Servers
+
+You can add custom LSP servers by specifying the command and file extensions:
+
+```json title="opencode.json"
+{
+ "$schema": "https://opencode.ai/config.json",
+ "lsp": {
+ "custom-lsp": {
+ "command": ["custom-lsp-server", "--stdio"],
+ "extensions": [".custom"]
+ }
+ }
+}
+```
+
+### Configuration Options
+
+Each LSP server configuration supports these properties:
+
+| Property | Type | Description |
+| ---------------- | -------- | ------------------------------------------------- |
+| `disabled` | boolean | Set to `true` to disable the LSP server |
+| `command` | string[] | The command to start the LSP server |
+| `extensions` | string[] | File extensions this LSP server should handle |
+| `env` | object | Environment variables to set when starting server |
+| `initialization` | object | Initialization options to send to the LSP server |
+
+## How It Works
+
+When opencode opens a file, it:
+
+1. Checks the file extension against all enabled LSP servers
+2. Starts the appropriate LSP server if not already running
+3. Provides intelligent code analysis and editing capabilities
+
+This integration allows the LLM to better understand your codebase through features like diagnostics, go-to-definition, and find-references.
diff --git a/packages/web/src/pages/s/[id].astro b/packages/web/src/pages/s/[id].astro
index fadf0eb01..0e0170b66 100644
--- a/packages/web/src/pages/s/[id].astro
+++ b/packages/web/src/pages/s/[id].astro
@@ -70,6 +70,13 @@ const ogImage = `${config.socialCard}/opencode-share/${encodedTitle}.png?model=$
{
tag: "meta",
attrs: {
+ name: "robots",
+ content: "noindex",
+ }
+ },
+ {
+ tag: "meta",
+ attrs: {
property: "og:image",
content: ogImage,
},