summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHieu Nguyen <[email protected]>2025-10-17 06:08:36 +0700
committerGitHub <[email protected]>2025-10-16 18:08:36 -0500
commit92d9a0ec6106c2a51e389f06da5af6c742780e06 (patch)
tree7ee9c93d4655155f9f0c3a44b16c869c3b792661
parent2be9ed25906f2aa2e7525fa585ba6a3dd825eabf (diff)
downloadopencode-92d9a0ec6106c2a51e389f06da5af6c742780e06.tar.gz
opencode-92d9a0ec6106c2a51e389f06da5af6c742780e06.zip
feat: deno lsp (#3210)
Co-authored-by: hiunguynx <[email protected]> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
-rw-r--r--packages/opencode/src/lsp/server.ts37
-rw-r--r--packages/web/src/content/docs/lsp.mdx31
2 files changed, 50 insertions, 18 deletions
diff --git a/packages/opencode/src/lsp/server.ts b/packages/opencode/src/lsp/server.ts
index 17211da11..68d8c2a93 100644
--- a/packages/opencode/src/lsp/server.ts
+++ b/packages/opencode/src/lsp/server.ts
@@ -20,10 +20,20 @@ export namespace LSPServer {
type RootFunction = (file: string) => Promise<string | undefined>
- const NearestRoot = (patterns: string[]): RootFunction => {
+ const NearestRoot = (includePatterns: string[], excludePatterns?: string[]): RootFunction => {
return async (file) => {
+ if (excludePatterns) {
+ const excludedFiles = Filesystem.up({
+ targets: excludePatterns,
+ start: path.dirname(file),
+ stop: Instance.directory,
+ })
+ const excluded = await excludedFiles.next()
+ await excludedFiles.return()
+ if (excluded.value) return undefined
+ }
const files = Filesystem.up({
- targets: patterns,
+ targets: includePatterns,
start: path.dirname(file),
stop: Instance.directory,
})
@@ -42,9 +52,30 @@ export namespace LSPServer {
spawn(root: string): Promise<Handle | undefined>
}
+ export const Deno: Info = {
+ id: "deno",
+ root: NearestRoot(["deno.json", "deno.jsonc"]),
+ extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs"],
+ async spawn(root) {
+ const deno = Bun.which("deno")
+ if (!deno) {
+ log.info("deno not found, please install deno first")
+ return
+ }
+ return {
+ process: spawn(deno, ["lsp"], {
+ cwd: root,
+ }),
+ }
+ },
+ }
+
export const Typescript: Info = {
id: "typescript",
- root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
+ root: NearestRoot(
+ ["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"],
+ ["deno.json", "deno.jsonc"],
+ ),
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
async spawn(root) {
const tsserver = await Bun.resolve("typescript/lib/tsserver.js", Instance.directory).catch(() => {})
diff --git a/packages/web/src/content/docs/lsp.mdx b/packages/web/src/content/docs/lsp.mdx
index 247f1bd54..e81fa9cf9 100644
--- a/packages/web/src/content/docs/lsp.mdx
+++ b/packages/web/src/content/docs/lsp.mdx
@@ -11,21 +11,22 @@ 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 |
-| ---------- | ---------------------------------------------------- | ----------------------------------- |
-| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
-| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` 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 |
-| vue | .vue | Auto-installs for Vue projects |
-| rust | .rs | `rust-analyzer` command available |
-| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects |
-| svelte | .svelte | Auto-installs for Svelte projects |
-| jdtls | .java | `Java SDK (version 21+)` installed |
+| LSP Server | Extensions | Requirements |
+| ---------- | ---------------------------------------------------- | ------------------------------------------------------------ |
+| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
+| deno | .ts, .tsx, .js, .jsx, .mjs | `deno` command available (auto-detects deno.json/deno.jsonc) |
+| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` 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 |
+| vue | .vue | Auto-installs for Vue projects |
+| rust | .rs | `rust-analyzer` command available |
+| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects |
+| svelte | .svelte | Auto-installs for Svelte projects |
+| jdtls | .java | `Java SDK (version 21+)` installed |
LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met.