Skip to content

Commit 8917a4c

Browse files
authored
feat: add texlab language server and latexindent formatter (anomalyco#5251)
1 parent 5d7a52f commit 8917a4c

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

packages/opencode/src/format/formatter.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,12 @@ export const terraform: Info = {
275275
return Bun.which("terraform") !== null
276276
},
277277
}
278+
279+
export const latexindent: Info = {
280+
name: "latexindent",
281+
command: ["latexindent", "-w", "-s", "$FILE"],
282+
extensions: [".tex"],
283+
async enabled() {
284+
return Bun.which("latexindent") !== null
285+
},
286+
}

packages/opencode/src/lsp/server.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,4 +1386,88 @@ export namespace LSPServer {
13861386
}
13871387
},
13881388
}
1389+
1390+
export const TexLab: Info = {
1391+
id: "texlab",
1392+
extensions: [".tex", ".bib"],
1393+
root: NearestRoot([".latexmkrc", "latexmkrc", ".texlabroot", "texlabroot"]),
1394+
async spawn(root) {
1395+
let bin = Bun.which("texlab", {
1396+
PATH: process.env["PATH"] + ":" + Global.Path.bin,
1397+
})
1398+
1399+
if (!bin) {
1400+
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
1401+
log.info("downloading texlab from GitHub releases")
1402+
1403+
const response = await fetch("https://api.github.com/repos/latex-lsp/texlab/releases/latest")
1404+
if (!response.ok) {
1405+
log.error("Failed to fetch texlab release info")
1406+
return
1407+
}
1408+
1409+
const release = (await response.json()) as {
1410+
tag_name?: string
1411+
assets?: { name?: string; browser_download_url?: string }[]
1412+
}
1413+
const version = release.tag_name?.replace("v", "")
1414+
if (!version) {
1415+
log.error("texlab release did not include a version tag")
1416+
return
1417+
}
1418+
1419+
const platform = process.platform
1420+
const arch = process.arch
1421+
1422+
const texArch = arch === "arm64" ? "aarch64" : "x86_64"
1423+
const texPlatform = platform === "darwin" ? "macos" : platform === "win32" ? "windows" : "linux"
1424+
const ext = platform === "win32" ? "zip" : "tar.gz"
1425+
const assetName = `texlab-${texArch}-${texPlatform}.${ext}`
1426+
1427+
const assets = release.assets ?? []
1428+
const asset = assets.find((a) => a.name === assetName)
1429+
if (!asset?.browser_download_url) {
1430+
log.error(`Could not find asset ${assetName} in texlab release`)
1431+
return
1432+
}
1433+
1434+
const downloadResponse = await fetch(asset.browser_download_url)
1435+
if (!downloadResponse.ok) {
1436+
log.error("Failed to download texlab")
1437+
return
1438+
}
1439+
1440+
const tempPath = path.join(Global.Path.bin, assetName)
1441+
await Bun.file(tempPath).write(downloadResponse)
1442+
1443+
if (ext === "zip") {
1444+
await $`unzip -o -q ${tempPath}`.cwd(Global.Path.bin).nothrow()
1445+
}
1446+
if (ext === "tar.gz") {
1447+
await $`tar -xzf ${tempPath}`.cwd(Global.Path.bin).nothrow()
1448+
}
1449+
1450+
await fs.rm(tempPath, { force: true })
1451+
1452+
bin = path.join(Global.Path.bin, "texlab" + (platform === "win32" ? ".exe" : ""))
1453+
1454+
if (!(await Bun.file(bin).exists())) {
1455+
log.error("Failed to extract texlab binary")
1456+
return
1457+
}
1458+
1459+
if (platform !== "win32") {
1460+
await $`chmod +x ${bin}`.nothrow()
1461+
}
1462+
1463+
log.info("installed texlab", { bin })
1464+
}
1465+
1466+
return {
1467+
process: spawn(bin, {
1468+
cwd: root,
1469+
}),
1470+
}
1471+
},
1472+
}
13891473
}

0 commit comments

Comments
 (0)