跳到主要内容

代码执行命令和用户点菜单有什么差别?

结论​

用户点菜单时,宿主先用 when 决定这项出不出现,再执行命令。commands.executeCommand 是直接调用,不看 when。能执行不等于该显示。

展开​

菜单路径:

  1. 读 contributes.menus。
  2. 用当前上下文键计算 when。
  3. 条件为真才渲染。
  4. 点击后按命令 id 调用处理函数,并带上菜单声明的参数。

代码路径:

await vscode.commands.executeCommand("myext.hello", uri);

这里不会因为 editorLangId == typescript 不成立就拒绝执行。所以:

  • 想限制「只在某种文件右键出现」,把条件写在菜单上。
  • 处理函数自己仍要校验参数。别的插件和用户都可以 executeCommand 把意料外的参数传进来。
  • 调别的插件的命令也用 executeCommand,例如 vscode.open、workbench.action.quickOpen。对方没激活时,若该命令有激活事件,宿主会先激活再执行。

命令面板本质也是菜单 commandPalette。给命令加上 "when": "false" 可以从面板隐藏,但代码仍能调用。这常用来做只给内部用的命令。

快捷键同样只负责触发,不额外加一层权限。

容易讲错的点​

  • when 是显示条件,不是安全边界。
  • executeCommand 的参数不会经过菜单那份 arguments 自动合并,调用方要自己传。
  • 命令不存在时 Promise reject。调用可选插件的命令前,先看 vscode.extensions.getExtension。