mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-23 02:34:21 +01:00
feat: support lua lsp (#3402)
This commit is contained in:
@@ -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,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ OpenCode comes with several built-in LSP servers for popular languages:
|
|||||||
| svelte | .svelte | Auto-installs for Svelte projects |
|
| svelte | .svelte | Auto-installs for Svelte projects |
|
||||||
| astro | .astro | Auto-installs for Astro projects |
|
| astro | .astro | Auto-installs for Astro projects |
|
||||||
| jdtls | .java | `Java SDK (version 21+)` installed |
|
| 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.
|
LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user