فهرست منبع

LSP: fix SimpleRoots to actually search in the root directory (#795)

Frank Denis 7 ماه پیش
والد
کامیت
727fe6f942
2فایلهای تغییر یافته به همراه108 افزوده شده و 2 حذف شده
  1. 106 2
      packages/opencode/src/lsp/server.ts
  2. 2 0
      packages/opencode/src/tool/ls.ts

+ 106 - 2
packages/opencode/src/lsp/server.ts

@@ -24,9 +24,8 @@ export namespace LSPServer {
 
   const SimpleRoots = (patterns: string[]): RootsFunction => {
     return async (app) => {
-      const glob = `**/*/{${patterns.join(",")}}`
       const files = await Ripgrep.files({
-        glob: [glob],
+        glob: patterns.map(p => `**/${p}`),
         cwd: app.path.root,
       })
       const dirs = files.map((file) => path.dirname(file))
@@ -239,4 +238,109 @@ export namespace LSPServer {
       }
     },
   }
+
+  export const Zls: Info = {
+    id: "zls",
+    extensions: [".zig", ".zon"],
+    roots: SimpleRoots(["build.zig"]),
+    async spawn(_, root) {
+      let bin = Bun.which("zls", {
+        PATH: process.env["PATH"] + ":" + Global.Path.bin,
+      })
+
+      if (!bin) {
+        const zig = Bun.which("zig")
+        if (!zig) {
+          log.error("Zig is required to use zls. Please install Zig first.")
+          return
+        }
+
+        log.info("downloading zls from GitHub releases")
+
+        const releaseResponse = await fetch("https://api.github.com/repos/zigtools/zls/releases/latest")
+        if (!releaseResponse.ok) {
+          log.error("Failed to fetch zls release info")
+          return
+        }
+
+        const release = await releaseResponse.json()
+
+        const platform = process.platform
+        const arch = process.arch
+        let assetName = ""
+
+        let zlsArch: string = arch
+        if (arch === "arm64") zlsArch = "aarch64"
+        else if (arch === "x64") zlsArch = "x86_64"
+        else if (arch === "ia32") zlsArch = "x86"
+
+        let zlsPlatform: string = platform
+        if (platform === "darwin") zlsPlatform = "macos"
+        else if (platform === "win32") zlsPlatform = "windows"
+
+        const ext = platform === "win32" ? "zip" : "tar.xz"
+
+        assetName = `zls-${zlsArch}-${zlsPlatform}.${ext}`
+
+        const supportedCombos = [
+          "zls-x86_64-linux.tar.xz",
+          "zls-x86_64-macos.tar.xz",
+          "zls-x86_64-windows.zip",
+          "zls-aarch64-linux.tar.xz",
+          "zls-aarch64-macos.tar.xz",
+          "zls-aarch64-windows.zip",
+          "zls-x86-linux.tar.xz",
+          "zls-x86-windows.zip",
+        ]
+
+        if (!supportedCombos.includes(assetName)) {
+          log.error(`Platform ${platform} and architecture ${arch} is not supported by zls`)
+          return
+        }
+
+        const asset = release.assets.find((a: any) => a.name === assetName)
+        if (!asset) {
+          log.error(`Could not find asset ${assetName} in latest zls release`)
+          return
+        }
+
+        const downloadUrl = asset.browser_download_url
+        const downloadResponse = await fetch(downloadUrl)
+        if (!downloadResponse.ok) {
+          log.error("Failed to download zls")
+          return
+        }
+
+        const tempPath = path.join(Global.Path.bin, assetName)
+        await Bun.file(tempPath).write(downloadResponse)
+
+        if (ext === "zip") {
+          await $`unzip -o -q ${tempPath}`.cwd(Global.Path.bin).nothrow()
+        } else {
+          await $`tar -xf ${tempPath}`.cwd(Global.Path.bin).nothrow()
+        }
+
+        await fs.rm(tempPath, { force: true })
+
+        bin = path.join(Global.Path.bin, "zls" + (platform === "win32" ? ".exe" : ""))
+
+        if (!(await Bun.file(bin).exists())) {
+          log.error("Failed to extract zls binary")
+          return
+        }
+
+        if (platform !== "win32") {
+          await $`chmod +x ${bin}`.nothrow()
+        }
+
+        log.info(`installed zls`, { bin })
+      }
+
+      return {
+        process: spawn(bin, {
+          cwd: root,
+        }),
+      }
+    },
+  }
 }

+ 2 - 0
packages/opencode/src/tool/ls.ts

@@ -16,6 +16,8 @@ export const IGNORE_PATTERNS = [
   "obj/",
   ".idea/",
   ".vscode/",
+  ".zig-cache/",
+  "zig-out",
 ]
 
 const LIMIT = 100