诊断集合谁创建谁清理,全量还是增量?
结论
诊断集合由插件创建并持有,停用时随订阅释放。对同一个 URI,常规做法是用这一轮的完整结果覆盖,而不是在旧结果上无脑追加。计算过程可以增量,写进集合时按文件替换。
展开
const collection = vscode.languages.createDiagnosticCollection("myext");
context.subscriptions.push(collection);
collection.set(document.uri, [
new vscode.Diagnostic(range, "未使用的变量", vscode.DiagnosticSeverity.Warning)
]);
集合的名字 myext 是来源,问题面板里会分组。一个插件可以有多份集合,例如语法和类型分开,互不影响。
覆盖语义:set(uri, diagnostics) 用新数组替换该 URI 的旧诊断。文件没问题就 set(uri, []) 或 delete(uri)。如果每次都往一个外部数组里追加再塞回去,又忘了去掉已修复的项,波浪线会越积越多。
触发时机通常是文档变化、保存或构建结束。按键时要防抖,例如 300 毫秒内只诊断最后一版,并用 document.version 丢掉过期结果。
关闭文档时可以清掉这份诊断,避免问题面板留着已经关掉的缓冲区。插件停用必须释放集合,否则波浪线还在,来源却已经没了。
容易讲错的点
- 不要去改别人的集合。你也拿不到别人的集合对象。每个插件只清自己的。
Diagnostic.range要用当前文档坐标。文件已经变了,就不要把旧范围写进去。- 诊断不是代码操作。修复动作放在代码操作提供器里,用诊断码把两边关联起来。