improvements to LSP process on quiesce

This commit is contained in:
2026-02-15 20:05:46 -08:00
parent 24048eadf1
commit 197e3525bf

View File

@@ -22,61 +22,66 @@ import { TextDocument } from "vscode-languageserver-textdocument";
const connection = createConnection(ProposedFeatures.all); const connection = createConnection(ProposedFeatures.all);
const documents = new TextDocuments(TextDocument); const documents = new TextDocuments(TextDocument);
// waiting for whomever to send accumulated changes
const DELAY_AFTER_SEND = 200
// waiting for typing to quiesce (and it seems accumulated changes have a delay between them)
const DELAY_AFTER_CHANGE = 100
// the last is the most important to the user, but we run FIFO // the last is the most important to the user, but we run FIFO
// to ensure dependencies are seen in causal order // to ensure dependencies are seen in causal order
let changes: TextDocument[] = [] let changes: TextDocument[] = []
let running: NodeJS.Timeout | undefined let running = false
let lastChange = 0 let lastChange = 0
function addChange(doc: TextDocument) { function addChange(doc: TextDocument) {
console.log('enqueue', doc.uri) console.log('enqueue', doc.uri)
// drop stale pending changes // drop stale pending changes
let before = changes.length let before = changes.length
changes = changes.filter(ch => ch.uri != doc.uri) changes = changes.filter(ch => ch.uri != doc.uri)
console.log('DROP', before - changes.length); console.log('DROPPED', before - changes.length);
changes.push(doc) changes.push(doc)
lastChange = +new Date() lastChange = +new Date()
// I'm not sure if this timeout is a big deal if (!running) runChange()
if (!running) running = setTimeout(runChange, DELAY_AFTER_CHANGE)
} }
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
function runChange() { async function runChange() {
let now = +new Date() try {
if ( now - lastChange < DELAY_AFTER_CHANGE) running = setTimeout(runChange, DELAY_AFTER_CHANGE); running = true;
while (changes.length) {
console.log('LOOP TOP')
// Wait until things stop changing
let prev = lastChange
while (1) {
await sleep(100)
if (prev == lastChange) break
prev = lastChange
console.log('DELAY')
}
let doc = changes.shift() let doc = changes.shift()
if (!doc) { if (!doc) {
running = undefined running = false
return return
} }
const uri = doc.uri const uri = doc.uri
const start = +new Date() const start = +new Date()
const diagnostics = LSP_checkFile(doc.uri) const diagnostics = LSP_checkFile(doc.uri)
const end = +new Date() const end = +new Date()
connection.sendDiagnostics({uri,diagnostics})
console.log('CHECK', doc.uri, 'in', end - start); console.log('CHECK', doc.uri, 'in', end - start);
console.log("GOT\n",JSON.stringify(diagnostics, null, ' ')) await sleep(1);
running = undefined if (!changes.find(ch => ch.uri === uri)) {
// If we just sent one, it seems that we need to give vscode some time to send the rest connection.sendDiagnostics({ uri, diagnostics })
// Otherwise, for Elab.newt, we hit 1.8s for each character typed. } else {
// 1 ms doesn't work, so I guess we don't have the changes accumulated locally. console.log('STALE result not sent for', uri)
running = setTimeout(runChange, DELAY_AFTER_SEND) }
}
} finally {
running = false;
}
} }
documents.onDidChangeContent(async (change) => { documents.onDidChangeContent(async (change) => {
console.log('DIDCHANGE', change.document.uri) console.log('DIDCHANGE', change.document.uri)
const uri = change.document.uri; const uri = change.document.uri;
const text = change.document.getText(); const text = change.document.getText();
// update/invalidate happens now, check happens on quiesce.
LSP_updateFile(uri, text); LSP_updateFile(uri, text);
// we defer the check to let all of the changes file in.
addChange(change.document); addChange(change.document);
// const diagnostics = LSP_checkFile(uri);
// console.log(`Got ${JSON.stringify(diagnostics, null, ' ')}`)
// connection.sendDiagnostics({ uri, diagnostics })
}); });
connection.onHover((params): Hover | null => { connection.onHover((params): Hover | null => {