mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 09:44:21 +01:00
fix lsp diagnostic accurancy
This commit is contained in:
@@ -12,6 +12,7 @@ import { Bus } from "../bus"
|
||||
import z from "zod"
|
||||
import type { LSPServer } from "./server"
|
||||
import { NamedError } from "../util/error"
|
||||
import { withTimeout } from "../util/timeout"
|
||||
|
||||
export namespace LSPClient {
|
||||
const log = Log.create({ service: "lsp.client" })
|
||||
@@ -52,7 +53,9 @@ export namespace LSPClient {
|
||||
log.info("textDocument/publishDiagnostics", {
|
||||
path,
|
||||
})
|
||||
const exists = diagnostics.has(path)
|
||||
diagnostics.set(path, params.diagnostics)
|
||||
if (!exists && serverID === "typescript") return
|
||||
Bus.publish(Event.Diagnostics, { path, serverID })
|
||||
})
|
||||
connection.onRequest("workspace/configuration", async () => {
|
||||
@@ -61,7 +64,7 @@ export namespace LSPClient {
|
||||
connection.listen()
|
||||
|
||||
log.info("sending initialize", { id: serverID })
|
||||
await Promise.race([
|
||||
await withTimeout(
|
||||
connection.sendRequest("initialize", {
|
||||
processId: server.process.pid,
|
||||
workspaceFolders: [
|
||||
@@ -88,12 +91,10 @@ export namespace LSPClient {
|
||||
},
|
||||
},
|
||||
}),
|
||||
new Promise((_, reject) => {
|
||||
setTimeout(() => {
|
||||
reject(new InitializeError({ serverID }))
|
||||
}, 5_000)
|
||||
}),
|
||||
])
|
||||
5_000,
|
||||
).catch(() => {
|
||||
throw new InitializeError({ serverID })
|
||||
})
|
||||
await connection.sendNotification("initialized", {})
|
||||
log.info("initialized")
|
||||
|
||||
@@ -116,36 +117,28 @@ export namespace LSPClient {
|
||||
const file = Bun.file(input.path)
|
||||
const text = await file.text()
|
||||
const version = files[input.path]
|
||||
if (version === undefined) {
|
||||
log.info("textDocument/didOpen", input)
|
||||
if (version !== undefined) {
|
||||
diagnostics.delete(input.path)
|
||||
const extension = path.extname(input.path)
|
||||
const languageId = LANGUAGE_EXTENSIONS[extension] ?? "plaintext"
|
||||
await connection.sendNotification("textDocument/didOpen", {
|
||||
await connection.sendNotification("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri: `file://` + input.path,
|
||||
languageId,
|
||||
version: 0,
|
||||
text,
|
||||
},
|
||||
})
|
||||
files[input.path] = 0
|
||||
return
|
||||
}
|
||||
|
||||
log.info("textDocument/didChange", input)
|
||||
log.info("textDocument/didOpen", input)
|
||||
diagnostics.delete(input.path)
|
||||
await connection.sendNotification("textDocument/didChange", {
|
||||
const extension = path.extname(input.path)
|
||||
const languageId = LANGUAGE_EXTENSIONS[extension] ?? "plaintext"
|
||||
await connection.sendNotification("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri: `file://` + input.path,
|
||||
version: ++files[input.path],
|
||||
languageId,
|
||||
version: 0,
|
||||
text,
|
||||
},
|
||||
contentChanges: [
|
||||
{
|
||||
text,
|
||||
},
|
||||
],
|
||||
})
|
||||
files[input.path] = 0
|
||||
return
|
||||
},
|
||||
},
|
||||
get diagnostics() {
|
||||
@@ -157,35 +150,30 @@ export namespace LSPClient {
|
||||
: path.resolve(app.path.cwd, input.path)
|
||||
log.info("waiting for diagnostics", input)
|
||||
let unsub: () => void
|
||||
let timeout: NodeJS.Timeout
|
||||
return await Promise.race([
|
||||
new Promise<void>(async (resolve) => {
|
||||
return await withTimeout(
|
||||
new Promise<void>((resolve) => {
|
||||
unsub = Bus.subscribe(Event.Diagnostics, (event) => {
|
||||
if (
|
||||
event.properties.path === input.path &&
|
||||
event.properties.serverID === result.serverID
|
||||
) {
|
||||
log.info("got diagnostics", input)
|
||||
clearTimeout(timeout)
|
||||
unsub?.()
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}),
|
||||
new Promise<void>((resolve) => {
|
||||
timeout = setTimeout(() => {
|
||||
log.info("timed out refreshing diagnostics", input)
|
||||
unsub?.()
|
||||
resolve()
|
||||
}, 5000)
|
||||
}),
|
||||
])
|
||||
5000,
|
||||
).finally(() => {
|
||||
unsub?.()
|
||||
})
|
||||
},
|
||||
async shutdown() {
|
||||
log.info("shutting down")
|
||||
log.info("shutting down", { serverID })
|
||||
connection.end()
|
||||
connection.dispose()
|
||||
server.process.kill("SIGTERM")
|
||||
log.info("shutdown", { serverID })
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user