Monaco Editor中registerCompletionItemProvider如何更新或注销?
关于动态更新SQL代码补全提供者的解决方案
VS Code 的languages.registerCompletionItemProviderAPI 调用后会返回一个可释放对象(Disposable),你可以通过该对象实现旧补全提供者的注销,无需承担多提供者同时生效的问题。
实现方式1:注销旧提供者后注册新提供者
- 首先在扩展全局作用域声明一个变量,用于存储当前生效的补全提供者实例
- 每次需要更新补全逻辑前,先调用存储实例的
dispose()方法注销旧提供者 - 注册新的补全提供者,将返回的新实例赋值给全局存储变量
参考代码示例:
import * as vscode from 'vscode'; // 全局存储当前补全提供者实例 let currentSQLCompletionProvider: vscode.Disposable | undefined; export function updateSQLCompletions(context: vscode.ExtensionContext) { // 注销旧的补全提供者 if (currentSQLCompletionProvider) { currentSQLCompletionProvider.dispose(); } // 注册新的补全提供者 currentSQLCompletionProvider = vscode.languages.registerCompletionItemProvider( 'sql', { provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { // 此处返回你动态生成的最新补全项列表 const completions: vscode.CompletionItem[] = []; // 你的自定义补全逻辑 return completions; } } // 可选参数:自定义触发字符,例如 ['.', '"', "'"] ); // 加入扩展上下文销毁队列,扩展卸载时自动释放 context.subscriptions.push(currentSQLCompletionProvider); }
实现方式2:直接复用现有提供者(更推荐)
不需要反复注销重注册提供者,只需要在provideCompletionItems方法内部读取最新的补全数据源即可:
- 把补全需要用到的动态数据存在全局可访问的变量里
- 需要更新补全建议时,仅更新这个全局变量的值即可
- 补全触发时
provideCompletionItems会自动读取最新的数据生成补全项,性能开销更小
示例逻辑:
import * as vscode from 'vscode'; // 全局存储补全数据源 let sqlCompletionData: vscode.CompletionItem[] = []; // 仅注册一次补全提供者 vscode.languages.registerCompletionItemProvider('sql', { provideCompletionItems() { // 直接返回最新的补全数据即可 return sqlCompletionData; } }); // 需要更新补全建议时,直接修改sqlCompletionData的值就行,不需要重新注册提供者 function updateCompletionData(newData: vscode.CompletionItem[]) { sqlCompletionData = newData; }
内容的提问来源于stack exchange,提问作者wtartanus
相关产品推荐
相关产品推荐

