feat: support lua lsp (#3402)

This commit is contained in:
Hieu Nguyen
2025-10-24 22:37:11 +07:00
committed by GitHub
parent 883b71ac36
commit 483fcdaddb
2 changed files with 123 additions and 0 deletions

View File

@@ -838,4 +838,126 @@ export namespace LSPServer {
}
},
}
export const LuaLS: Info = {
id: "lua-ls",
root: NearestRoot([
".luarc.json",
".luarc.jsonc",
".luacheckrc",
".stylua.toml",
"stylua.toml",
"selene.toml",
"selene.yml",
]),
extensions: [".lua"],
async spawn(root) {
let bin = Bun.which("lua-language-server", {
PATH: process.env["PATH"] + ":" + Global.Path.bin,
})
if (!bin) {
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("downloading lua-language-server from GitHub releases")
const releaseResponse = await fetch("https://api.github.com/repos/LuaLS/lua-language-server/releases/latest")
if (!releaseResponse.ok) {
log.error("Failed to fetch lua-language-server release info")
return
}
const release = await releaseResponse.json()
const platform = process.platform
const arch = process.arch
let assetName = ""
let lualsArch: string = arch
if (arch === "arm64") lualsArch = "arm64"
else if (arch === "x64") lualsArch = "x64"
else if (arch === "ia32") lualsArch = "ia32"
let lualsPlatform: string = platform
if (platform === "darwin") lualsPlatform = "darwin"
else if (platform === "linux") lualsPlatform = "linux"
else if (platform === "win32") lualsPlatform = "win32"
const ext = platform === "win32" ? "zip" : "tar.gz"
assetName = `lua-language-server-${release.tag_name}-${lualsPlatform}-${lualsArch}.${ext}`
const supportedCombos = [
"darwin-arm64.tar.gz",
"darwin-x64.tar.gz",
"linux-x64.tar.gz",
"linux-arm64.tar.gz",
"win32-x64.zip",
"win32-ia32.zip",
]
const assetSuffix = `${lualsPlatform}-${lualsArch}.${ext}`
if (!supportedCombos.includes(assetSuffix)) {
log.error(`Platform ${platform} and architecture ${arch} is not supported by lua-language-server`)
return
}
const asset = release.assets.find((a: any) => a.name === assetName)
if (!asset) {
log.error(`Could not find asset ${assetName} in latest lua-language-server release`)
return
}
const downloadUrl = asset.browser_download_url
const downloadResponse = await fetch(downloadUrl)
if (!downloadResponse.ok) {
log.error("Failed to download lua-language-server")
return
}
const tempPath = path.join(Global.Path.bin, assetName)
await Bun.file(tempPath).write(downloadResponse)
// Unlike zls which is a single self-contained binary,
// lua-language-server needs supporting files (meta/, locale/, etc.)
// Extract entire archive to dedicated directory to preserve all files
const installDir = path.join(Global.Path.bin, `lua-language-server-${lualsArch}-${lualsPlatform}`)
// Remove old installation if exists
const stats = await fs.stat(installDir).catch(() => undefined)
if (stats) {
await fs.rm(installDir, { force: true, recursive: true })
}
await fs.mkdir(installDir, { recursive: true })
if (ext === "zip") {
await $`unzip -o -q ${tempPath} -d ${installDir}`.quiet().nothrow()
} else {
await $`tar -xzf ${tempPath} -C ${installDir}`.nothrow()
}
await fs.rm(tempPath, { force: true })
// Binary is located in bin/ subdirectory within the extracted archive
bin = path.join(installDir, "bin", "lua-language-server" + (platform === "win32" ? ".exe" : ""))
if (!(await Bun.file(bin).exists())) {
log.error("Failed to extract lua-language-server binary")
return
}
if (platform !== "win32") {
await $`chmod +x ${bin}`.nothrow()
}
log.info(`installed lua-language-server`, { bin })
}
return {
process: spawn(bin, {
cwd: root,
}),
}
},
}
}

View File

@@ -28,6 +28,7 @@ OpenCode comes with several built-in LSP servers for popular languages:
| svelte | .svelte | Auto-installs for Svelte projects |
| astro | .astro | Auto-installs for Astro projects |
| jdtls | .java | `Java SDK (version 21+)` installed |
| lua-ls | .lua | Auto-installs for Lua projects |
LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met.