瀏覽代碼

feat(lsp): add Tinymist LSP support for Typst (#5933)

ja 3 月之前
父節點
當前提交
cd8ecf9722
共有 3 個文件被更改,包括 97 次插入0 次删除
  1. 2 0
      packages/opencode/src/lsp/language.ts
  2. 94 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

@@ -111,4 +111,6 @@ export const LANGUAGE_EXTENSIONS: Record<string, string> = {
   ".tfvars": "terraform-vars",
   ".hcl": "hcl",
   ".nix": "nix",
+  ".typ": "typst",
+  ".typc": "typst",
 } as const

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

@@ -1798,4 +1798,98 @@ export namespace LSPServer {
       }
     },
   }
+
+  export const Tinymist: Info = {
+    id: "tinymist",
+    extensions: [".typ", ".typc"],
+    root: NearestRoot(["typst.toml"]),
+    async spawn(root) {
+      let bin = Bun.which("tinymist", {
+        PATH: process.env["PATH"] + path.delimiter + Global.Path.bin,
+      })
+
+      if (!bin) {
+        if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
+        log.info("downloading tinymist from GitHub releases")
+
+        const response = await fetch("https://api.github.com/repos/Myriad-Dreamin/tinymist/releases/latest")
+        if (!response.ok) {
+          log.error("Failed to fetch tinymist release info")
+          return
+        }
+
+        const release = (await response.json()) as {
+          tag_name?: string
+          assets?: { name?: string; browser_download_url?: string }[]
+        }
+
+        const platform = process.platform
+        const arch = process.arch
+
+        const tinymistArch = arch === "arm64" ? "aarch64" : "x86_64"
+        let tinymistPlatform: string
+        let ext: string
+
+        if (platform === "darwin") {
+          tinymistPlatform = "apple-darwin"
+          ext = "tar.gz"
+        } else if (platform === "win32") {
+          tinymistPlatform = "pc-windows-msvc"
+          ext = "zip"
+        } else {
+          tinymistPlatform = "unknown-linux-gnu"
+          ext = "tar.gz"
+        }
+
+        const assetName = `tinymist-${tinymistArch}-${tinymistPlatform}.${ext}`
+
+        const assets = release.assets ?? []
+        const asset = assets.find((a) => a.name === assetName)
+        if (!asset?.browser_download_url) {
+          log.error(`Could not find asset ${assetName} in tinymist release`)
+          return
+        }
+
+        const downloadResponse = await fetch(asset.browser_download_url)
+        if (!downloadResponse.ok) {
+          log.error("Failed to download tinymist")
+          return
+        }
+
+        const tempPath = path.join(Global.Path.bin, assetName)
+        await Bun.file(tempPath).write(downloadResponse)
+
+        if (ext === "zip") {
+          const ok = await Archive.extractZip(tempPath, Global.Path.bin)
+            .then(() => true)
+            .catch((error) => {
+              log.error("Failed to extract tinymist archive", { error })
+              return false
+            })
+          if (!ok) return
+        } else {
+          await $`tar -xzf ${tempPath} --strip-components=1`.cwd(Global.Path.bin).quiet().nothrow()
+        }
+
+        await fs.rm(tempPath, { force: true })
+
+        bin = path.join(Global.Path.bin, "tinymist" + (platform === "win32" ? ".exe" : ""))
+
+        if (!(await Bun.file(bin).exists())) {
+          log.error("Failed to extract tinymist binary")
+          return
+        }
+
+        if (platform !== "win32") {
+          await $`chmod +x ${bin}`.quiet().nothrow()
+        }
+
+        log.info("installed tinymist", { bin })
+      }
+
+      return {
+        process: spawn(bin, { cwd: root }),
+      }
+    },
+  }
 }

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

@@ -37,6 +37,7 @@ OpenCode comes with several built-in LSP servers for popular languages:
 | sourcekit-lsp      | .swift, .objc, .objcpp                                              | `swift` installed (`xcode` on macOS)                         |
 | svelte             | .svelte                                                             | Auto-installs for Svelte projects                            |
 | terraform          | .tf, .tfvars                                                        | Auto-installs from GitHub releases                           |
+| tinymist           | .typ, .typc                                                         | Auto-installs from GitHub releases                           |
 | typescript         | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts                        | `typescript` dependency in project                           |
 | vue                | .vue                                                                | Auto-installs for Vue projects                               |
 | yaml-ls            | .yaml, .yml                                                         | Auto-installs Red Hat yaml-language-server                   |