Merge pull request #2487 from code-yeongyu/fix/issue-2431-lsp-path-resolution
fix: unify LSP server PATH resolution between detection and spawn
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Readable, Writable } from "node:stream"
|
||||
import { delimiter } from "path"
|
||||
import {
|
||||
createMessageConnection,
|
||||
StreamMessageReader,
|
||||
@@ -7,6 +8,7 @@ import {
|
||||
} from "vscode-jsonrpc/node"
|
||||
import type { Diagnostic, ResolvedServer } from "./types"
|
||||
import { spawnProcess, type UnifiedProcess } from "./lsp-process"
|
||||
import { getLspServerAdditionalPathBases } from "./server-path-bases"
|
||||
import { log } from "../../shared/logger"
|
||||
export class LSPClientTransport {
|
||||
protected proc: UnifiedProcess | null = null
|
||||
@@ -18,12 +20,22 @@ export class LSPClientTransport {
|
||||
|
||||
constructor(protected root: string, protected server: ResolvedServer) {}
|
||||
async start(): Promise<void> {
|
||||
const env = {
|
||||
...process.env,
|
||||
...this.server.env,
|
||||
}
|
||||
const pathValue = process.platform === "win32" ? env.PATH ?? env.Path ?? "" : env.PATH ?? ""
|
||||
const spawnPath = [pathValue, ...getLspServerAdditionalPathBases(this.root)]
|
||||
.filter(Boolean)
|
||||
.join(delimiter)
|
||||
if (process.platform === "win32" && env.Path !== undefined) {
|
||||
env.Path = spawnPath
|
||||
}
|
||||
env.PATH = spawnPath
|
||||
|
||||
this.proc = spawnProcess(this.server.command, {
|
||||
cwd: this.root,
|
||||
env: {
|
||||
...process.env,
|
||||
...this.server.env,
|
||||
},
|
||||
env,
|
||||
})
|
||||
if (!this.proc) {
|
||||
throw new Error(`Failed to spawn LSP server: ${this.server.command.join(" ")}`)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { existsSync } from "fs"
|
||||
import { join } from "path"
|
||||
import { delimiter, join } from "path"
|
||||
|
||||
import { getOpenCodeConfigDir, getDataDir } from "../../shared"
|
||||
import { getLspServerAdditionalPathBases } from "./server-path-bases"
|
||||
|
||||
export function isServerInstalled(command: string[]): boolean {
|
||||
if (command.length === 0) return false
|
||||
@@ -31,8 +31,7 @@ export function isServerInstalled(command: string[]): boolean {
|
||||
pathEnv = process.env.Path || ""
|
||||
}
|
||||
|
||||
const pathSeparator = isWindows ? ";" : ":"
|
||||
const paths = pathEnv.split(pathSeparator)
|
||||
const paths = pathEnv.split(delimiter)
|
||||
|
||||
for (const p of paths) {
|
||||
for (const suffix of exts) {
|
||||
@@ -42,17 +41,7 @@ export function isServerInstalled(command: string[]): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
const cwd = process.cwd()
|
||||
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
|
||||
const dataDir = join(getDataDir(), "opencode")
|
||||
const additionalBases = [
|
||||
join(cwd, "node_modules", ".bin"),
|
||||
join(configDir, "bin"),
|
||||
join(configDir, "node_modules", ".bin"),
|
||||
join(dataDir, "bin"),
|
||||
]
|
||||
|
||||
for (const base of additionalBases) {
|
||||
for (const base of getLspServerAdditionalPathBases(process.cwd())) {
|
||||
for (const suffix of exts) {
|
||||
if (existsSync(join(base, cmd + suffix))) {
|
||||
return true
|
||||
|
||||
16
src/tools/lsp/server-path-bases.ts
Normal file
16
src/tools/lsp/server-path-bases.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { join } from "path"
|
||||
|
||||
import { getDataDir, getOpenCodeConfigDir } from "../../shared"
|
||||
|
||||
export function getLspServerAdditionalPathBases(workingDirectory: string): string[] {
|
||||
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
|
||||
const dataDir = join(getDataDir(), "opencode")
|
||||
|
||||
return [
|
||||
join(workingDirectory, "node_modules", ".bin"),
|
||||
join(configDir, "bin"),
|
||||
join(configDir, "node_modules", ".bin"),
|
||||
join(dataDir, "bin"),
|
||||
join(dataDir, "bin", "node_modules", ".bin"),
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user