diff options
| author | adamdotdevin <[email protected]> | 2025-08-11 19:21:59 -0500 |
|---|---|---|
| committer | adamdotdevin <[email protected]> | 2025-08-11 19:21:59 -0500 |
| commit | ee0519aacc22db40f99365c6759d2f1715931a5c (patch) | |
| tree | 933200c467ead81fc7c4c7df1f66c6c7f0ac1cd6 /packages | |
| parent | dec1e3fddabe253a2aa22f4bcfcee8ddfbcb9766 (diff) | |
| download | opencode-ee0519aacc22db40f99365c6759d2f1715931a5c.tar.gz opencode-ee0519aacc22db40f99365c6759d2f1715931a5c.zip | |
feat: add clangd for cpp
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/opencode/src/lsp/server.ts | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/packages/opencode/src/lsp/server.ts b/packages/opencode/src/lsp/server.ts index cf78fe7bf..3da5a7e28 100644 --- a/packages/opencode/src/lsp/server.ts +++ b/packages/opencode/src/lsp/server.ts @@ -421,4 +421,81 @@ export namespace LSPServer { } }, } + + export const Clangd: Info = { + id: "clangd", + root: NearestRoot(["compile_commands.json", "compile_flags.txt", ".clangd", "CMakeLists.txt", "Makefile"]), + extensions: [".c", ".cpp", ".cc", ".cxx", ".c++", ".h", ".hpp", ".hh", ".hxx", ".h++"], + async spawn(_, root) { + let bin = Bun.which("clangd", { + PATH: process.env["PATH"] + ":" + Global.Path.bin, + }) + if (!bin) { + log.info("downloading clangd from GitHub releases") + + const releaseResponse = await fetch("https://api.github.com/repos/clangd/clangd/releases/latest") + if (!releaseResponse.ok) { + log.error("Failed to fetch clangd release info") + return + } + + const release = await releaseResponse.json() + + const platform = process.platform + let assetName = "" + + if (platform === "darwin") { + assetName = "clangd-mac-" + } else if (platform === "linux") { + assetName = "clangd-linux-" + } else if (platform === "win32") { + assetName = "clangd-windows-" + } else { + log.error(`Platform ${platform} is not supported by clangd auto-download`) + return + } + + assetName += release.tag_name + ".zip" + + const asset = release.assets.find((a: any) => a.name === assetName) + if (!asset) { + log.error(`Could not find asset ${assetName} in latest clangd release`) + return + } + + const downloadUrl = asset.browser_download_url + const downloadResponse = await fetch(downloadUrl) + if (!downloadResponse.ok) { + log.error("Failed to download clangd") + return + } + + const zipPath = path.join(Global.Path.bin, "clangd.zip") + await Bun.file(zipPath).write(downloadResponse) + + await $`unzip -o -q ${zipPath}`.cwd(Global.Path.bin).nothrow() + await fs.rm(zipPath, { force: true }) + + const extractedDir = path.join(Global.Path.bin, assetName.replace(".zip", "")) + bin = path.join(extractedDir, "bin", "clangd" + (platform === "win32" ? ".exe" : "")) + + if (!(await Bun.file(bin).exists())) { + log.error("Failed to extract clangd binary") + return + } + + if (platform !== "win32") { + await $`chmod +x ${bin}`.nothrow() + } + + log.info(`installed clangd`, { bin }) + } + + return { + process: spawn(bin, ["--background-index", "--clang-tidy"], { + cwd: root, + }), + } + }, + } } |
