瀏覽代碼

feat: Add kotlin lsp integration (#6601)

Troy Gaines 1 月之前
父節點
當前提交
586207adb4
共有 3 個文件被更改,包括 86 次插入0 次删除
  1. 2 0
      packages/opencode/src/lsp/language.ts
  2. 83 0
      packages/opencode/src/lsp/server.ts
  3. 1 0
      packages/web/src/content/docs/lsp.mdx

+ 2 - 0
packages/opencode/src/lsp/language.ts

@@ -45,6 +45,8 @@ export const LANGUAGE_EXTENSIONS: Record<string, string> = {
   ".ini": "ini",
   ".ini": "ini",
   ".java": "java",
   ".java": "java",
   ".js": "javascript",
   ".js": "javascript",
+  ".kt": "kotlin",
+  ".kts": "kotlin",
   ".jsx": "javascriptreact",
   ".jsx": "javascriptreact",
   ".json": "json",
   ".json": "json",
   ".tex": "latex",
   ".tex": "latex",

+ 83 - 0
packages/opencode/src/lsp/server.ts

@@ -1209,6 +1209,89 @@ export namespace LSPServer {
     },
     },
   }
   }
 
 
+  export const KotlinLS: Info = {
+    id: "kotlin-ls",
+    extensions: [".kt", ".kts"],
+    root: NearestRoot(["build.gradle", "build.gradle.kts", "settings.gradle.kts", "pom.xml"]),
+    async spawn(root) {
+      const distPath = path.join(Global.Path.bin, "kotlin-ls")
+      const launcherScript =
+        process.platform === "win32" ? path.join(distPath, "kotlin-lsp.cmd") : path.join(distPath, "kotlin-lsp.sh")
+      const installed = await Bun.file(launcherScript).exists()
+      if (!installed) {
+        if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
+        log.info("Downloading Kotlin Language Server from GitHub.")
+
+        const releaseResponse = await fetch("https://api.github.com/repos/Kotlin/kotlin-lsp/releases/latest")
+        if (!releaseResponse.ok) {
+          log.error("Failed to fetch kotlin-lsp release info")
+          return
+        }
+
+        const release = await releaseResponse.json()
+        const version = release.name?.replace(/^v/, '')
+
+        if (!version) {
+          log.error("Could not determine Kotlin LSP version from release")
+          return
+        }
+
+        const platform = process.platform
+        const arch = process.arch
+
+        let kotlinArch: string = arch
+        if (arch === "arm64") kotlinArch = "aarch64"
+        else if (arch === "x64") kotlinArch = "x64"
+
+        let kotlinPlatform: string = platform
+        if (platform === "darwin") kotlinPlatform = "mac"
+        else if (platform === "linux") kotlinPlatform = "linux"
+        else if (platform === "win32") kotlinPlatform = "win"
+
+        const supportedCombos = [
+          "mac-x64", "mac-aarch64",
+          "linux-x64", "linux-aarch64",
+          "win-x64", "win-aarch64"
+        ]
+
+        const combo = `${kotlinPlatform}-${kotlinArch}`
+
+        if (!supportedCombos.includes(combo)) {
+          log.error(`Platform ${platform}/${arch} is not supported by Kotlin LSP`)
+          return
+        }
+
+        const assetName = `kotlin-lsp-${version}-${kotlinPlatform}-${kotlinArch}.zip`
+        const releaseURL = `https://download-cdn.jetbrains.com/kotlin-lsp/${version}/${assetName}`
+
+        await fs.mkdir(distPath, { recursive: true })
+        const archivePath = path.join(distPath, "kotlin-ls.zip")
+        await $`curl -L -o '${archivePath}' '${releaseURL}'`.quiet().nothrow()
+        const ok = await Archive.extractZip(archivePath, distPath)
+          .then(() => true)
+          .catch((error) => {
+            log.error("Failed to extract Kotlin LS archive", { error })
+            return false
+          })
+        if (!ok) return
+        await fs.rm(archivePath, { force: true })
+        if (process.platform !== "win32") {
+          await $`chmod +x ${launcherScript}`.quiet().nothrow()
+        }
+        log.info("Installed Kotlin Language Server", { path: launcherScript })
+      }
+      if (!(await Bun.file(launcherScript).exists())) {
+        log.error(`Failed to locate the Kotlin LS launcher script in the installed directory: ${distPath}.`)
+        return
+      }
+      return {
+        process: spawn(launcherScript, ["--stdio"], {
+          cwd: root,
+        }),
+      }
+    },
+  }
+
   export const YamlLS: Info = {
   export const YamlLS: Info = {
     id: "yaml-ls",
     id: "yaml-ls",
     extensions: [".yaml", ".yml"],
     extensions: [".yaml", ".yml"],

+ 1 - 0
packages/web/src/content/docs/lsp.mdx

@@ -26,6 +26,7 @@ OpenCode comes with several built-in LSP servers for popular languages:
 | gleam              | .gleam                                                              | `gleam` command available                                    |
 | gleam              | .gleam                                                              | `gleam` command available                                    |
 | gopls              | .go                                                                 | `go` command available                                       |
 | gopls              | .go                                                                 | `go` command available                                       |
 | jdtls              | .java                                                               | `Java SDK (version 21+)` installed                           |
 | jdtls              | .java                                                               | `Java SDK (version 21+)` installed                           |
+| kotlin-ls          | .kt, .kts                                                           | Auto-installs for Kotlin projects                            |
 | lua-ls             | .lua                                                                | Auto-installs for Lua projects                               |
 | lua-ls             | .lua                                                                | Auto-installs for Lua projects                               |
 | nixd               | .nix                                                                | `nixd` command available                                     |
 | nixd               | .nix                                                                | `nixd` command available                                     |
 | ocaml-lsp          | .ml, .mli                                                           | `ocamllsp` command available                                 |
 | ocaml-lsp          | .ml, .mli                                                           | `ocamllsp` command available                                 |