При разработке языкового сервера, который обслуживает диагностику для XML документов, я столкнулся с проблемой, когда существует несколько источников диагностики для одного документа.
В этом небольшом примере показана проблема:
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
const diagnosticsCollection: vscode.DiagnosticCollection = vscode.languages.createDiagnosticCollection(
'test'
);
const diagnosticsCollection2: vscode.DiagnosticCollection = vscode.languages.createDiagnosticCollection(
'test2'
);
vscode.workspace.onDidChangeTextDocument((event: vscode.TextDocumentChangeEvent) => {
const document = event.document;
const diagnostics: vscode.Diagnostic[] = [];
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
const index = line.text.indexOf('hello');
if (index >= 0) {
diagnostics.push(
new vscode.Diagnostic(
new vscode.Range(i, index, i, index),
'The word hello',
vscode.DiagnosticSeverity.Warning,
)
);
}
}
diagnosticsCollection.set(document.uri, diagnostics);
});
vscode.workspace.onDidSaveTextDocument((document: vscode.TextDocument) => {
const diagnostics: vscode.Diagnostic[] = [];
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
const index = line.text.indexOf('world');
if (index >= 0) {
diagnostics.push(
new vscode.Diagnostic(
new vscode.Range(i, index, i, index),
'The word world',
vscode.DiagnosticSeverity.Error,
)
);
}
}
diagnosticsCollection2.set(document.uri, diagnostics);
});
}
Это результат предупреждений установки события изменения и ошибок установки события сохранения:
Первое событие (изменение) обновляет диагностику для "привет" слова. Но когда они установлены, vscode повторно применяет теперь уже устаревшую «мировую» диагностику. Это приводит к тому, что маркеры ошибок оказываются не на своем месте, поскольку слово перемещается. Через секунду событие сохранения обновляет «мировую» диагностику.
Реальная проблема та же, но она вызвана другим языковым расширением сервера, обеспечивающим проверку XSD с диагностикой, в то время как наш языковой сервер предоставляет диагностику, определяющую решение c для того же документа.
Есть ли способ справиться с этим?