You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为上下文菜单命令识别对应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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:30:44