Monaco Editor快速查找选中符号/行号的回调实现问题
解决Monaco Editor Ctrl+Shift+O选中后触发异步加载的问题
核心思路
放弃尝试获取IQuickInputService(独立Monaco环境下该服务不存在,仅VS Code扩展内可用),转而通过覆盖默认的转到符号/行动作结合光标位置变化监听,精准捕获用户通过Ctrl+Shift+O完成选择后的事件,触发异步加载逻辑。
具体实现
- 标记动作激活状态:覆盖原
editor.action.goToSymbol和editor.action.gotoLine动作,在打开面板时标记状态为激活。 - 监听光标变化:当光标位置变化且动作激活状态为真时,判定为用户完成选择,执行异步加载并重置状态。
// 保存原动作实例 const originalGoToSymbol = editor.getAction('editor.action.goToSymbol'); const originalGoToLine = editor.getAction('editor.action.gotoLine'); let isGoToActionActive = false; // 覆盖转到符号动作 editor.registerAction({ id: 'editor.action.goToSymbol', label: originalGoToSymbol.label, run: async (accessor, editorInstance) => { isGoToActionActive = true; // 执行原动作打开面板 await originalGoToSymbol.run(accessor, editorInstance); } }); // 覆盖转到行动作 editor.registerAction({ id: 'editor.action.gotoLine', label: originalGoToLine.label, run: async (accessor, editorInstance) => { isGoToActionActive = true; await originalGoToLine.run(accessor, editorInstance); } }); // 监听光标位置变化,捕获选择完成事件 editor.onDidChangeCursorPosition((event) => { if (isGoToActionActive) { isGoToActionActive = false; // 获取模型真实行号,不受视图显示范围限制 const targetLine = event.position.lineNumber; // 执行异步加载逻辑 loadDataAsync(targetLine).then((data) => { // 处理加载后的数据,比如更新编辑器内容或其他操作 console.log('加载完成:', data); }); } }); // 示例异步加载函数 function loadDataAsync(lineNumber) { return new Promise((resolve) => { setTimeout(() => { resolve(`行${lineNumber}的异步数据`); }, 1000); }); }
关键说明
event.position.lineNumber是模型中的真实行号,不受编辑器视图显示范围影响,之前你遇到的“返回100行”问题,大概率是误获取了视图可见范围的行号而非模型行号。- 状态标记
isGoToActionActive用于区分用户是通过Ctrl+Shift+O触发的光标变化,还是普通编辑操作的光标移动,避免误触发异步加载。
内容的提问来源于stack exchange,提问作者undercover grill
相关产品推荐
相关产品推荐

