improvements to LSP process on quiesce
This commit is contained in:
@@ -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);
|
await sleep(1);
|
||||||
console.log("GOT\n",JSON.stringify(diagnostics, null, ' '))
|
if (!changes.find(ch => ch.uri === uri)) {
|
||||||
running = undefined
|
connection.sendDiagnostics({ uri, diagnostics })
|
||||||
// If we just sent one, it seems that we need to give vscode some time to send the rest
|
} else {
|
||||||
// Otherwise, for Elab.newt, we hit 1.8s for each character typed.
|
console.log('STALE result not sent for', uri)
|
||||||
// 1 ms doesn't work, so I guess we don't have the changes accumulated locally.
|
}
|
||||||
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 => {
|
||||||
|
|||||||
Reference in New Issue
Block a user