summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEric Shirley <[email protected]>2025-12-19 01:17:20 -0500
committerGitHub <[email protected]>2025-12-19 00:17:20 -0600
commit14146428dd3eeec8fb827b08a6ac209c71698872 (patch)
tree793eac6acfea070d853a224498a96ab2d20c1634
parent26d0280f70760a1212636683c1b5753afa4e70d8 (diff)
downloadopencode-14146428dd3eeec8fb827b08a6ac209c71698872.tar.gz
opencode-14146428dd3eeec8fb827b08a6ac209c71698872.zip
lsp: add oxlint server (#5570)
-rw-r--r--packages/opencode/src/lsp/server.ts73
-rw-r--r--packages/web/src/content/docs/lsp.mdx55
2 files changed, 100 insertions, 28 deletions
diff --git a/packages/opencode/src/lsp/server.ts b/packages/opencode/src/lsp/server.ts
index f0ec2adb4..4db0e7237 100644
--- a/packages/opencode/src/lsp/server.ts
+++ b/packages/opencode/src/lsp/server.ts
@@ -4,7 +4,7 @@ import os from "os"
import { Global } from "../global"
import { Log } from "../util/log"
import { BunProc } from "../bun"
-import { $ } from "bun"
+import { $, readableStreamToText } from "bun"
import fs from "fs/promises"
import { Filesystem } from "../util/filesystem"
import { Instance } from "../project/instance"
@@ -216,6 +216,77 @@ export namespace LSPServer {
},
}
+ export const Oxlint: Info = {
+ id: "oxlint",
+ root: NearestRoot([
+ ".oxlintrc.json",
+ "package-lock.json",
+ "bun.lockb",
+ "bun.lock",
+ "pnpm-lock.yaml",
+ "yarn.lock",
+ "package.json",
+ ]),
+ extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue", ".astro", ".svelte"],
+ async spawn(root) {
+ const ext = process.platform === "win32" ? ".cmd" : ""
+
+ const serverTarget = path.join("node_modules", ".bin", "oxc_language_server" + ext)
+ const lintTarget = path.join("node_modules", ".bin", "oxlint" + ext)
+
+ const resolveBin = async (target: string) => {
+ const localBin = path.join(root, target)
+ if (await Bun.file(localBin).exists()) return localBin
+
+ const candidates = Filesystem.up({
+ targets: [target],
+ start: root,
+ stop: Instance.worktree,
+ })
+ const first = await candidates.next()
+ await candidates.return()
+ if (first.value) return first.value
+
+ return undefined
+ }
+
+ let lintBin = await resolveBin(lintTarget)
+ if (!lintBin) {
+ const found = Bun.which("oxlint")
+ if (found) lintBin = found
+ }
+
+ if (lintBin) {
+ const proc = Bun.spawn([lintBin, "--help"], { stdout: "pipe" })
+ await proc.exited
+ const help = await readableStreamToText(proc.stdout)
+ if (help.includes("--lsp")) {
+ return {
+ process: spawn(lintBin, ["--lsp"], {
+ cwd: root,
+ }),
+ }
+ }
+ }
+
+ let serverBin = await resolveBin(serverTarget)
+ if (!serverBin) {
+ const found = Bun.which("oxc_language_server")
+ if (found) serverBin = found
+ }
+ if (serverBin) {
+ return {
+ process: spawn(serverBin, [], {
+ cwd: root,
+ }),
+ }
+ }
+
+ log.info("oxlint not found, please install oxlint")
+ return
+ },
+ }
+
export const Biome: Info = {
id: "biome",
root: NearestRoot([
diff --git a/packages/web/src/content/docs/lsp.mdx b/packages/web/src/content/docs/lsp.mdx
index a96cf5324..6572574f2 100644
--- a/packages/web/src/content/docs/lsp.mdx
+++ b/packages/web/src/content/docs/lsp.mdx
@@ -11,33 +11,34 @@ OpenCode integrates with your Language Server Protocol (LSP) to help the LLM int
OpenCode comes with several built-in LSP servers for popular languages:
-| LSP Server | Extensions | Requirements |
-| ------------------ | ---------------------------------------------------- | ------------------------------------------------------------ |
-| astro | .astro | Auto-installs for Astro projects |
-| bash | .sh, .bash, .zsh, .ksh | Auto-installs bash-language-server |
-| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects |
-| csharp | .cs | `.NET SDK` installed |
-| dart | .dart | `dart` command available |
-| deno | .ts, .tsx, .js, .jsx, .mjs | `deno` command available (auto-detects deno.json/deno.jsonc) |
-| elixir-ls | .ex, .exs | `elixir` command available |
-| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` dependency in project |
-| fsharp | .fs, .fsi, .fsx, .fsscript | `.NET SDK` installed |
-| gleam | .gleam | `gleam` command available |
-| gopls | .go | `go` command available |
-| jdtls | .java | `Java SDK (version 21+)` installed |
-| lua-ls | .lua | Auto-installs for Lua projects |
-| ocaml-lsp | .ml, .mli | `ocamllsp` command available |
-| php intelephense | .php | Auto-installs for PHP projects |
-| pyright | .py, .pyi | `pyright` dependency installed |
-| ruby-lsp (rubocop) | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available |
-| rust | .rs | `rust-analyzer` command available |
-| sourcekit-lsp | .swift, .objc, .objcpp | `swift` installed (`xcode` on macOS) |
-| svelte | .svelte | Auto-installs for Svelte projects |
-| terraform | .tf, .tfvars | Auto-installs from GitHub releases |
-| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
-| vue | .vue | Auto-installs for Vue projects |
-| yaml-ls | .yaml, .yml | Auto-installs Red Hat yaml-language-server |
-| zls | .zig, .zon | `zig` command available |
+| LSP Server | Extensions | Requirements |
+| ------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------ |
+| astro | .astro | Auto-installs for Astro projects |
+| bash | .sh, .bash, .zsh, .ksh | Auto-installs bash-language-server |
+| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects |
+| csharp | .cs | `.NET SDK` installed |
+| dart | .dart | `dart` command available |
+| deno | .ts, .tsx, .js, .jsx, .mjs | `deno` command available (auto-detects deno.json/deno.jsonc) |
+| elixir-ls | .ex, .exs | `elixir` command available |
+| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` dependency in project |
+| fsharp | .fs, .fsi, .fsx, .fsscript | `.NET SDK` installed |
+| gleam | .gleam | `gleam` command available |
+| gopls | .go | `go` command available |
+| jdtls | .java | `Java SDK (version 21+)` installed |
+| lua-ls | .lua | Auto-installs for Lua projects |
+| ocaml-lsp | .ml, .mli | `ocamllsp` command available |
+| oxlint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue, .astro, .svelte | `oxlint` dependency in project |
+| php intelephense | .php | Auto-installs for PHP projects |
+| pyright | .py, .pyi | `pyright` dependency installed |
+| ruby-lsp (rubocop) | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available |
+| rust | .rs | `rust-analyzer` command available |
+| sourcekit-lsp | .swift, .objc, .objcpp | `swift` installed (`xcode` on macOS) |
+| svelte | .svelte | Auto-installs for Svelte projects |
+| terraform | .tf, .tfvars | Auto-installs from GitHub releases |
+| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
+| vue | .vue | Auto-installs for Vue projects |
+| yaml-ls | .yaml, .yml | Auto-installs Red Hat yaml-language-server |
+| zls | .zig, .zon | `zig` command available |
LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met.