如何为上下文菜单命令识别对应VS Code Webview实例?
问题:如何确定Webview上下文菜单对应的实例?
我正在构建一款可创建多个Webview的VS Code扩展,每个文本编辑器文档对应一个Webview。我需要让用户在Webview中右键执行命令时,命令能知道触发操作的Webview实例(或者命令面板调用时的激活/聚焦实例),从而执行正确的操作。但上下文菜单的回调只能收到{webview:<viewType>}作为参数,请问该如何确定这个上下文菜单来自哪个具体的Webview实例?
简化的扩展代码
import * as vscode from 'vscode'; import { commands, TextEditor, window } from 'vscode'; import { Viewer } from './viewer'; export function activate(ctx: vscode.ExtensionContext) { let manager = new MyExtManager(); const subs = ctx.subscriptions; subs.push(commands.registerCommand('myExt.show', () => { manager.showWebview(ctx.extensionUri); })); subs.push(commands.registerCommand('myExt.myCtxItem', (wv) => { // 这里需要唯一标识符来定位对应的编辑器 console.log(wv); })); } class MyExtManager { private viewerByDoc: Map<vscode.Uri, Viewer> = new Map(); public showWebview(extensionURI: vscode.Uri) { const editor: TextEditor | undefined = window.activeTextEditor; const doc = editor?.document; if (doc && doc.languageId === "xml") { let viewerForDoc = this.viewerByDoc.get(doc.uri); if (viewerForDoc) { viewerForDoc.reveal(); } else { const panel = vscode.window.createWebviewPanel( 'myxmlviewer', `My Viewer for ${doc.uri}`, vscode.ViewColumn.Beside ); panel.onDidDispose(() => this.viewerByDoc.delete(doc.uri)); viewerForDoc = new Viewer(editor, panel) this.viewerByDoc.set(doc.uri, viewerForDoc); } } } }
已调研的方案
- 无法使用
vscode.window.active*系列API,因为没有类似activeTextEditor的活跃Webview集合接口。 - 未找到WebviewPanel获得焦点时的回调,无法通过全局变量追踪当前最新的实例。
- 未找到Webview上下文菜单打开时的回调,无法在菜单打开时将对应实例存储到全局变量。
临时方案思路
目前想到的唯一办法是给每个查看器实例设置唯一的viewType参数,但不确定该参数的设计意图,这种用法可能不符合官方预期。
上下文菜单配置(package.json)
{ "contributes": { "commands": [ { "category": "XML Viewer", "command": "myExt.show", "title": "Open to the Side" }, { "category": "XML Viewer", "command": "myExt.myCtxItem", "title": "Do a Thing Here" } ], "menus": { "webview/context": [ { "command": "myExt.myCtxItem", "group": "xmlViewer" } ] } } }
内容的提问来源于stack exchange,提问作者Phrogz
相关产品推荐
相关产品推荐

