fix(lsp): prevent stale diagnostics by syncing didChange
This commit is contained in:
+41
-12
@@ -215,6 +215,8 @@ export class LSPClient {
|
||||
private proc: Subprocess<"pipe", "pipe", "pipe"> | null = null
|
||||
private connection: MessageConnection | null = null
|
||||
private openedFiles = new Set<string>()
|
||||
private documentVersions = new Map<string, number>()
|
||||
private lastSyncedText = new Map<string, string>()
|
||||
private stderrBuffer: string[] = []
|
||||
private processExited = false
|
||||
private diagnosticsStore = new Map<string, Diagnostic[]>()
|
||||
@@ -432,23 +434,50 @@ export class LSPClient {
|
||||
|
||||
async openFile(filePath: string): Promise<void> {
|
||||
const absPath = resolve(filePath)
|
||||
if (this.openedFiles.has(absPath)) return
|
||||
|
||||
const uri = pathToFileURL(absPath).href
|
||||
const text = readFileSync(absPath, "utf-8")
|
||||
const ext = extname(absPath)
|
||||
const languageId = getLanguageId(ext)
|
||||
|
||||
this.sendNotification("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri: pathToFileURL(absPath).href,
|
||||
languageId,
|
||||
version: 1,
|
||||
text,
|
||||
},
|
||||
if (!this.openedFiles.has(absPath)) {
|
||||
const ext = extname(absPath)
|
||||
const languageId = getLanguageId(ext)
|
||||
const version = 1
|
||||
|
||||
this.sendNotification("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId,
|
||||
version,
|
||||
text,
|
||||
},
|
||||
})
|
||||
|
||||
this.openedFiles.add(absPath)
|
||||
this.documentVersions.set(uri, version)
|
||||
this.lastSyncedText.set(uri, text)
|
||||
await new Promise((r) => setTimeout(r, 1000))
|
||||
return
|
||||
}
|
||||
|
||||
const prevText = this.lastSyncedText.get(uri)
|
||||
if (prevText === text) {
|
||||
return
|
||||
}
|
||||
|
||||
const nextVersion = (this.documentVersions.get(uri) ?? 1) + 1
|
||||
this.documentVersions.set(uri, nextVersion)
|
||||
this.lastSyncedText.set(uri, text)
|
||||
|
||||
this.sendNotification("textDocument/didChange", {
|
||||
textDocument: { uri, version: nextVersion },
|
||||
contentChanges: [{ text }],
|
||||
})
|
||||
this.openedFiles.add(absPath)
|
||||
|
||||
await new Promise((r) => setTimeout(r, 1000))
|
||||
// Some servers update diagnostics only after save
|
||||
this.sendNotification("textDocument/didSave", {
|
||||
textDocument: { uri },
|
||||
text,
|
||||
})
|
||||
}
|
||||
|
||||
async definition(filePath: string, line: number, character: number): Promise<unknown> {
|
||||
|
||||
Reference in New Issue
Block a user