|
@@ -88,9 +88,7 @@ export namespace LSPServer {
|
|
|
),
|
|
),
|
|
|
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
|
|
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
|
|
|
async spawn(root) {
|
|
async spawn(root) {
|
|
|
- const tsserver = await Bun.resolve("typescript/lib/tsserver.js", Instance.directory).catch(
|
|
|
|
|
- () => {},
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const tsserver = await Bun.resolve("typescript/lib/tsserver.js", Instance.directory).catch(() => {})
|
|
|
if (!tsserver) return
|
|
if (!tsserver) return
|
|
|
const proc = spawn(BunProc.which(), ["x", "typescript-language-server", "--stdio"], {
|
|
const proc = spawn(BunProc.which(), ["x", "typescript-language-server", "--stdio"], {
|
|
|
cwd: root,
|
|
cwd: root,
|
|
@@ -113,13 +111,7 @@ export namespace LSPServer {
|
|
|
export const Vue: Info = {
|
|
export const Vue: Info = {
|
|
|
id: "vue",
|
|
id: "vue",
|
|
|
extensions: [".vue"],
|
|
extensions: [".vue"],
|
|
|
- root: NearestRoot([
|
|
|
|
|
- "package-lock.json",
|
|
|
|
|
- "bun.lockb",
|
|
|
|
|
- "bun.lock",
|
|
|
|
|
- "pnpm-lock.yaml",
|
|
|
|
|
- "yarn.lock",
|
|
|
|
|
- ]),
|
|
|
|
|
|
|
+ root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
|
|
async spawn(root) {
|
|
async spawn(root) {
|
|
|
let binary = Bun.which("vue-language-server")
|
|
let binary = Bun.which("vue-language-server")
|
|
|
const args: string[] = []
|
|
const args: string[] = []
|
|
@@ -167,31 +159,17 @@ export namespace LSPServer {
|
|
|
|
|
|
|
|
export const ESLint: Info = {
|
|
export const ESLint: Info = {
|
|
|
id: "eslint",
|
|
id: "eslint",
|
|
|
- root: NearestRoot([
|
|
|
|
|
- "package-lock.json",
|
|
|
|
|
- "bun.lockb",
|
|
|
|
|
- "bun.lock",
|
|
|
|
|
- "pnpm-lock.yaml",
|
|
|
|
|
- "yarn.lock",
|
|
|
|
|
- ]),
|
|
|
|
|
|
|
+ root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
|
|
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"],
|
|
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"],
|
|
|
async spawn(root) {
|
|
async spawn(root) {
|
|
|
const eslint = await Bun.resolve("eslint", Instance.directory).catch(() => {})
|
|
const eslint = await Bun.resolve("eslint", Instance.directory).catch(() => {})
|
|
|
if (!eslint) return
|
|
if (!eslint) return
|
|
|
log.info("spawning eslint server")
|
|
log.info("spawning eslint server")
|
|
|
- const serverPath = path.join(
|
|
|
|
|
- Global.Path.bin,
|
|
|
|
|
- "vscode-eslint",
|
|
|
|
|
- "server",
|
|
|
|
|
- "out",
|
|
|
|
|
- "eslintServer.js",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js")
|
|
|
if (!(await Bun.file(serverPath).exists())) {
|
|
if (!(await Bun.file(serverPath).exists())) {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
log.info("downloading and building VS Code ESLint server")
|
|
log.info("downloading and building VS Code ESLint server")
|
|
|
- const response = await fetch(
|
|
|
|
|
- "https://github.com/microsoft/vscode-eslint/archive/refs/heads/main.zip",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const response = await fetch("https://github.com/microsoft/vscode-eslint/archive/refs/heads/main.zip")
|
|
|
if (!response.ok) return
|
|
if (!response.ok) return
|
|
|
|
|
|
|
|
const zipPath = path.join(Global.Path.bin, "vscode-eslint.zip")
|
|
const zipPath = path.join(Global.Path.bin, "vscode-eslint.zip")
|
|
@@ -316,25 +294,12 @@ export namespace LSPServer {
|
|
|
export const Pyright: Info = {
|
|
export const Pyright: Info = {
|
|
|
id: "pyright",
|
|
id: "pyright",
|
|
|
extensions: [".py", ".pyi"],
|
|
extensions: [".py", ".pyi"],
|
|
|
- root: NearestRoot([
|
|
|
|
|
- "pyproject.toml",
|
|
|
|
|
- "setup.py",
|
|
|
|
|
- "setup.cfg",
|
|
|
|
|
- "requirements.txt",
|
|
|
|
|
- "Pipfile",
|
|
|
|
|
- "pyrightconfig.json",
|
|
|
|
|
- ]),
|
|
|
|
|
|
|
+ root: NearestRoot(["pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile", "pyrightconfig.json"]),
|
|
|
async spawn(root) {
|
|
async spawn(root) {
|
|
|
let binary = Bun.which("pyright-langserver")
|
|
let binary = Bun.which("pyright-langserver")
|
|
|
const args = []
|
|
const args = []
|
|
|
if (!binary) {
|
|
if (!binary) {
|
|
|
- const js = path.join(
|
|
|
|
|
- Global.Path.bin,
|
|
|
|
|
- "node_modules",
|
|
|
|
|
- "pyright",
|
|
|
|
|
- "dist",
|
|
|
|
|
- "pyright-langserver.js",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const js = path.join(Global.Path.bin, "node_modules", "pyright", "dist", "pyright-langserver.js")
|
|
|
if (!(await Bun.file(js).exists())) {
|
|
if (!(await Bun.file(js).exists())) {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
await Bun.spawn([BunProc.which(), "install", "pyright"], {
|
|
await Bun.spawn([BunProc.which(), "install", "pyright"], {
|
|
@@ -352,11 +317,9 @@ export namespace LSPServer {
|
|
|
|
|
|
|
|
const initialization: Record<string, string> = {}
|
|
const initialization: Record<string, string> = {}
|
|
|
|
|
|
|
|
- const potentialVenvPaths = [
|
|
|
|
|
- process.env["VIRTUAL_ENV"],
|
|
|
|
|
- path.join(root, ".venv"),
|
|
|
|
|
- path.join(root, "venv"),
|
|
|
|
|
- ].filter((p): p is string => p !== undefined)
|
|
|
|
|
|
|
+ const potentialVenvPaths = [process.env["VIRTUAL_ENV"], path.join(root, ".venv"), path.join(root, "venv")].filter(
|
|
|
|
|
+ (p): p is string => p !== undefined,
|
|
|
|
|
+ )
|
|
|
for (const venvPath of potentialVenvPaths) {
|
|
for (const venvPath of potentialVenvPaths) {
|
|
|
const isWindows = process.platform === "win32"
|
|
const isWindows = process.platform === "win32"
|
|
|
const potentialPythonPath = isWindows
|
|
const potentialPythonPath = isWindows
|
|
@@ -407,9 +370,7 @@ export namespace LSPServer {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
log.info("downloading elixir-ls from GitHub releases")
|
|
log.info("downloading elixir-ls from GitHub releases")
|
|
|
|
|
|
|
|
- const response = await fetch(
|
|
|
|
|
- "https://github.com/elixir-lsp/elixir-ls/archive/refs/heads/master.zip",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const response = await fetch("https://github.com/elixir-lsp/elixir-ls/archive/refs/heads/master.zip")
|
|
|
if (!response.ok) return
|
|
if (!response.ok) return
|
|
|
const zipPath = path.join(Global.Path.bin, "elixir-ls.zip")
|
|
const zipPath = path.join(Global.Path.bin, "elixir-ls.zip")
|
|
|
await Bun.file(zipPath).write(response)
|
|
await Bun.file(zipPath).write(response)
|
|
@@ -459,9 +420,7 @@ export namespace LSPServer {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
log.info("downloading zls from GitHub releases")
|
|
log.info("downloading zls from GitHub releases")
|
|
|
|
|
|
|
|
- const releaseResponse = await fetch(
|
|
|
|
|
- "https://api.github.com/repos/zigtools/zls/releases/latest",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const releaseResponse = await fetch("https://api.github.com/repos/zigtools/zls/releases/latest")
|
|
|
if (!releaseResponse.ok) {
|
|
if (!releaseResponse.ok) {
|
|
|
log.error("Failed to fetch zls release info")
|
|
log.error("Failed to fetch zls release info")
|
|
|
return
|
|
return
|
|
@@ -636,13 +595,7 @@ export namespace LSPServer {
|
|
|
|
|
|
|
|
export const Clangd: Info = {
|
|
export const Clangd: Info = {
|
|
|
id: "clangd",
|
|
id: "clangd",
|
|
|
- root: NearestRoot([
|
|
|
|
|
- "compile_commands.json",
|
|
|
|
|
- "compile_flags.txt",
|
|
|
|
|
- ".clangd",
|
|
|
|
|
- "CMakeLists.txt",
|
|
|
|
|
- "Makefile",
|
|
|
|
|
- ]),
|
|
|
|
|
|
|
+ root: NearestRoot(["compile_commands.json", "compile_flags.txt", ".clangd", "CMakeLists.txt", "Makefile"]),
|
|
|
extensions: [".c", ".cpp", ".cc", ".cxx", ".c++", ".h", ".hpp", ".hh", ".hxx", ".h++"],
|
|
extensions: [".c", ".cpp", ".cc", ".cxx", ".c++", ".h", ".hpp", ".hh", ".hxx", ".h++"],
|
|
|
async spawn(root) {
|
|
async spawn(root) {
|
|
|
let bin = Bun.which("clangd", {
|
|
let bin = Bun.which("clangd", {
|
|
@@ -652,9 +605,7 @@ export namespace LSPServer {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
log.info("downloading clangd from GitHub releases")
|
|
log.info("downloading clangd from GitHub releases")
|
|
|
|
|
|
|
|
- const releaseResponse = await fetch(
|
|
|
|
|
- "https://api.github.com/repos/clangd/clangd/releases/latest",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const releaseResponse = await fetch("https://api.github.com/repos/clangd/clangd/releases/latest")
|
|
|
if (!releaseResponse.ok) {
|
|
if (!releaseResponse.ok) {
|
|
|
log.error("Failed to fetch clangd release info")
|
|
log.error("Failed to fetch clangd release info")
|
|
|
return
|
|
return
|
|
@@ -723,24 +674,12 @@ export namespace LSPServer {
|
|
|
export const Svelte: Info = {
|
|
export const Svelte: Info = {
|
|
|
id: "svelte",
|
|
id: "svelte",
|
|
|
extensions: [".svelte"],
|
|
extensions: [".svelte"],
|
|
|
- root: NearestRoot([
|
|
|
|
|
- "package-lock.json",
|
|
|
|
|
- "bun.lockb",
|
|
|
|
|
- "bun.lock",
|
|
|
|
|
- "pnpm-lock.yaml",
|
|
|
|
|
- "yarn.lock",
|
|
|
|
|
- ]),
|
|
|
|
|
|
|
+ root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
|
|
async spawn(root) {
|
|
async spawn(root) {
|
|
|
let binary = Bun.which("svelteserver")
|
|
let binary = Bun.which("svelteserver")
|
|
|
const args: string[] = []
|
|
const args: string[] = []
|
|
|
if (!binary) {
|
|
if (!binary) {
|
|
|
- const js = path.join(
|
|
|
|
|
- Global.Path.bin,
|
|
|
|
|
- "node_modules",
|
|
|
|
|
- "svelte-language-server",
|
|
|
|
|
- "bin",
|
|
|
|
|
- "server.js",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const js = path.join(Global.Path.bin, "node_modules", "svelte-language-server", "bin", "server.js")
|
|
|
if (!(await Bun.file(js).exists())) {
|
|
if (!(await Bun.file(js).exists())) {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
await Bun.spawn([BunProc.which(), "install", "svelte-language-server"], {
|
|
await Bun.spawn([BunProc.which(), "install", "svelte-language-server"], {
|
|
@@ -775,17 +714,9 @@ export namespace LSPServer {
|
|
|
export const Astro: Info = {
|
|
export const Astro: Info = {
|
|
|
id: "astro",
|
|
id: "astro",
|
|
|
extensions: [".astro"],
|
|
extensions: [".astro"],
|
|
|
- root: NearestRoot([
|
|
|
|
|
- "package-lock.json",
|
|
|
|
|
- "bun.lockb",
|
|
|
|
|
- "bun.lock",
|
|
|
|
|
- "pnpm-lock.yaml",
|
|
|
|
|
- "yarn.lock",
|
|
|
|
|
- ]),
|
|
|
|
|
|
|
+ root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
|
|
async spawn(root) {
|
|
async spawn(root) {
|
|
|
- const tsserver = await Bun.resolve("typescript/lib/tsserver.js", Instance.directory).catch(
|
|
|
|
|
- () => {},
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const tsserver = await Bun.resolve("typescript/lib/tsserver.js", Instance.directory).catch(() => {})
|
|
|
if (!tsserver) {
|
|
if (!tsserver) {
|
|
|
log.info("typescript not found, required for Astro language server")
|
|
log.info("typescript not found, required for Astro language server")
|
|
|
return
|
|
return
|
|
@@ -795,14 +726,7 @@ export namespace LSPServer {
|
|
|
let binary = Bun.which("astro-ls")
|
|
let binary = Bun.which("astro-ls")
|
|
|
const args: string[] = []
|
|
const args: string[] = []
|
|
|
if (!binary) {
|
|
if (!binary) {
|
|
|
- const js = path.join(
|
|
|
|
|
- Global.Path.bin,
|
|
|
|
|
- "node_modules",
|
|
|
|
|
- "@astrojs",
|
|
|
|
|
- "language-server",
|
|
|
|
|
- "bin",
|
|
|
|
|
- "nodeServer.js",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const js = path.join(Global.Path.bin, "node_modules", "@astrojs", "language-server", "bin", "nodeServer.js")
|
|
|
if (!(await Bun.file(js).exists())) {
|
|
if (!(await Bun.file(js).exists())) {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
await Bun.spawn([BunProc.which(), "install", "@astrojs/language-server"], {
|
|
await Bun.spawn([BunProc.which(), "install", "@astrojs/language-server"], {
|
|
@@ -880,9 +804,7 @@ export namespace LSPServer {
|
|
|
.then(({ stdout }) => stdout.toString().trim())
|
|
.then(({ stdout }) => stdout.toString().trim())
|
|
|
const launcherJar = path.join(launcherDir, jarFileName)
|
|
const launcherJar = path.join(launcherDir, jarFileName)
|
|
|
if (!(await fs.exists(launcherJar))) {
|
|
if (!(await fs.exists(launcherJar))) {
|
|
|
- log.error(
|
|
|
|
|
- `Failed to locate the JDTLS launcher module in the installed directory: ${distPath}.`,
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ log.error(`Failed to locate the JDTLS launcher module in the installed directory: ${distPath}.`)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
const configFile = path.join(
|
|
const configFile = path.join(
|
|
@@ -948,9 +870,7 @@ export namespace LSPServer {
|
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
|
|
log.info("downloading lua-language-server from GitHub releases")
|
|
log.info("downloading lua-language-server from GitHub releases")
|
|
|
|
|
|
|
|
- const releaseResponse = await fetch(
|
|
|
|
|
- "https://api.github.com/repos/LuaLS/lua-language-server/releases/latest",
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const releaseResponse = await fetch("https://api.github.com/repos/LuaLS/lua-language-server/releases/latest")
|
|
|
if (!releaseResponse.ok) {
|
|
if (!releaseResponse.ok) {
|
|
|
log.error("Failed to fetch lua-language-server release info")
|
|
log.error("Failed to fetch lua-language-server release info")
|
|
|
return
|
|
return
|
|
@@ -987,9 +907,7 @@ export namespace LSPServer {
|
|
|
|
|
|
|
|
const assetSuffix = `${lualsPlatform}-${lualsArch}.${ext}`
|
|
const assetSuffix = `${lualsPlatform}-${lualsArch}.${ext}`
|
|
|
if (!supportedCombos.includes(assetSuffix)) {
|
|
if (!supportedCombos.includes(assetSuffix)) {
|
|
|
- log.error(
|
|
|
|
|
- `Platform ${platform} and architecture ${arch} is not supported by lua-language-server`,
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ log.error(`Platform ${platform} and architecture ${arch} is not supported by lua-language-server`)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1012,10 +930,7 @@ export namespace LSPServer {
|
|
|
// Unlike zls which is a single self-contained binary,
|
|
// Unlike zls which is a single self-contained binary,
|
|
|
// lua-language-server needs supporting files (meta/, locale/, etc.)
|
|
// lua-language-server needs supporting files (meta/, locale/, etc.)
|
|
|
// Extract entire archive to dedicated directory to preserve all files
|
|
// Extract entire archive to dedicated directory to preserve all files
|
|
|
- const installDir = path.join(
|
|
|
|
|
- Global.Path.bin,
|
|
|
|
|
- `lua-language-server-${lualsArch}-${lualsPlatform}`,
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ const installDir = path.join(Global.Path.bin, `lua-language-server-${lualsArch}-${lualsPlatform}`)
|
|
|
|
|
|
|
|
// Remove old installation if exists
|
|
// Remove old installation if exists
|
|
|
const stats = await fs.stat(installDir).catch(() => undefined)
|
|
const stats = await fs.stat(installDir).catch(() => undefined)
|
|
@@ -1040,11 +955,7 @@ export namespace LSPServer {
|
|
|
await fs.rm(tempPath, { force: true })
|
|
await fs.rm(tempPath, { force: true })
|
|
|
|
|
|
|
|
// Binary is located in bin/ subdirectory within the extracted archive
|
|
// Binary is located in bin/ subdirectory within the extracted archive
|
|
|
- bin = path.join(
|
|
|
|
|
- installDir,
|
|
|
|
|
- "bin",
|
|
|
|
|
- "lua-language-server" + (platform === "win32" ? ".exe" : ""),
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ bin = path.join(installDir, "bin", "lua-language-server" + (platform === "win32" ? ".exe" : ""))
|
|
|
|
|
|
|
|
if (!(await Bun.file(bin).exists())) {
|
|
if (!(await Bun.file(bin).exists())) {
|
|
|
log.error("Failed to extract lua-language-server binary")
|
|
log.error("Failed to extract lua-language-server binary")
|