ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

vscode 插件开发:view/item/context 右键菜单排序配置与验证

vscode 插件开发:view/item/context 右键菜单排序配置与验证 1. 右键菜单顺序为什么总是不听话如果你正在开发 VS Code 插件并且用到了 TreeView 或者自定义视图那你大概率踩过这个坑package.json里view/item/context的菜单项明明是按自己想要的顺序写的结果运行起来一看顺序全乱了。更让人抓狂的是有时候改一下when条件顺序又变了完全找不到规律。这个问题的核心在于VS Code 对view/item/context菜单的排序不是按照数组书写顺序来的。它有一套自己的排序规则主要依据两个字段——group和order。如果你不理解这套规则就会觉得菜单顺序是玄学。我试过在一个收藏夹插件里配置了七八个右键菜单项一开始没管group全部默认结果菜单顺序每次重启 VS Code 都可能不一样。后来把group和order理清楚顺序就完全可控了。这篇文章面向的是需要在 TreeView 或自定义视图中精确控制右键菜单顺序的插件开发者。我会给出可直接复制的package.json配置骨架演示group与order字段如何影响排序并带你做一次完整的验证帮你快速定位菜单顺序异常的根因。读完你就能明白为什么zbottom会跑到最后为什么sort1能排在sort2前面。在开始之前先明确一个概念view/item/context是 VS Code 菜单贡献点之一专门用于 TreeView 中单个节点的右键菜单。它和view/title视图标题栏按钮、editor/context编辑器右键是不同的贡献点排序规则也有差异。本文只聚焦view/item/context。2. 前置准备TaoToken 与开发环境在动手改配置之前先把环境理顺。如果你在开发过程中需要调用大模型能力来做代码补全、命令生成或者调试辅助可以用 TaoToken 来统一管理模型接入。它的 API 地址是 https://taotoken.net/api 兼容常见的 OpenAI 风格调用方式配置起来比较直接。对于插件开发本身你需要Node.js 18 以上npm 或 pnpm 均可VS Code 1.80 以上view/item/context的group排序行为在较新版本中更稳定Yeoman 的 VS Code 插件生成器或者一个已有的插件工程如果你还没有 API Key可以先到控制台创建一个https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsole 。创建后在 API Keys 页面复制出来https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc 里面有不同语言的调用示例。需要说明的是TaoToken 在这里的角色是帮你管理模型调用的入口不是替代 VS Code 编辑器本身。插件开发的主体工作还是在 VS Code 和你的代码仓库里完成。环境准备好之后我们进入正题package.json里到底怎么写。3. 可复制的 package.json 配置骨架先看一个完整的view/item/context配置骨架。这个骨架来自一个收藏夹插件的真实场景包含在资源管理器中打开从侧边栏打开删除上移下移置顶置底清空等菜单项。{ contributes: { menus: { view/item/context: [ { command: favourite.revealInOS.windows, when: isWindows view in ext:allFavouriteViews viewItem ~ /^resource/, group: navigation }, { command: favourite.openToSide, when: view in ext:allFavouriteViews viewItem ~ /^resource(Child)?$|^uri\\.resource(Child)?$/, group: navigation }, { command: favourite.deleteFavourite, when: view in ext:allFavouriteViews viewItem ~ /resource(\\.dir)?$/, group: operation }, { command: favourite.moveToTop, when: view in ext:allFavouriteViews viewItem ~ /resource(\\.dir)?$/, group: sort1 }, { command: favourite.moveUp, when: view in ext:allFavouriteViews viewItem ~ /resource(\\.dir)?$/, group: sort2 }, { command: favourite.moveDown, when: view in ext:allFavouriteViews viewItem ~ /resource(\\.dir)?$/, group: sort3 }, { command: favourite.moveToBottom, when: view in ext:allFavouriteViews viewItem ~ /resource(\\.dir)?$/, group: sort4 }, { command: favourite.deleteAllFavourite, when: view in ext:allFavouriteViews viewItem ~ /resource(\\.dir)?$/, group: zbottom } ] } } }这段配置里每个菜单项都有三个关键字段command、when、group。command指向你在commands里注册的命令 IDwhen决定这个菜单项在什么条件下显示group决定它排在哪个分组、以及分组内的顺序。排序规则可以总结成两句话第一不同 group 之间按 group 名称的字母顺序升序排列。navigation排在operation前面operation排在sort前面sort排在zbottom前面。这就是为什么zbottom用字母 z 开头——它会被排到最后。第二同一个 group 内可以用数字指定顺序。sort1排在sort2前面sort2排在sort3前面以此类推。如果不写数字同一 group 内的顺序就不保证稳定。这里有个容易忽略的点group的值是sort1这种形式时VS Code 会把前面的部分当作分组名后面的部分当作组内排序权重。所以sort1和sort2属于同一个sort分组只是组内顺序不同。再看when条件。view in ext:allFavouriteViews表示当前视图属于这个插件贡献的视图集合viewItem ~ /^resource/是正则匹配表示节点的上下文值以resource开头。viewItem的值来自你在TreeDataProvider的getTreeItem里设置的contextValue。如果你发现菜单项该显示的时候不显示先检查contextValue和when里的正则是否对得上。isWindows是一个内置的上下文键在 Windows 平台为真。类似的还有isMac、isLinux。这些键可以直接用在when里做平台判断。4. 验证排序从改配置到看结果配置写好了怎么验证顺序对不对最直接的办法是启动扩展开发宿主。在 VS Code 里打开你的插件工程按 F5 启动 Extension Development Host。这会打开一个新的 VS Code 窗口里面加载了你正在开发的插件。在新窗口里找到你的 TreeView右键点击一个节点观察菜单项的顺序。按照上面的配置你应该看到的分组顺序是顺序group菜单项1navigation在资源管理器中打开、从侧边栏打开2operation从收藏夹中删除3sort1上移至顶4sort2上移5sort3下移6sort4下移至底7zbottom清空收藏夹如果顺序不对按下面的步骤排查。第一步确认group拼写。navigation和operation是 VS Code 内置的常用分组名但sort和zbottom是自定义的。自定义分组名只要保持一致即可但要注意大小写敏感。Sort和sort会被当成两个不同的分组。第二步确认数字没有重复。如果两个菜单项都写了sort1它们的相对顺序就不确定。数字建议从 1 开始连续递增。第三步确认when条件没有把某些项过滤掉。如果某个菜单项没显示不是排序问题而是when没匹配上。可以在命令面板里运行Developer: Inspect Context Keys来查看当前上下文键的值。第四步确认没有其他扩展也在往view/item/context里加菜单项。多个扩展的菜单项会合并显示如果别的扩展也用了navigation分组它的项可能插在你的项中间。这种情况下你可以换一个更独特的自定义分组名来隔离。验证的时候我习惯把group临时改成差异很大的名字比如aaa、bbb、ccc这样一眼就能看出排序是否按字母升序走。确认规则生效后再改回语义化的名字。另外VS Code 的菜单排序在navigation分组内还有一个特殊行为这个分组通常被渲染在菜单的顶部区域和1_、2_这类数字前缀分组一起。如果你想让某个项绝对靠前用navigation是稳妥的选择。如果想让某个项绝对靠后用z开头的自定义分组名比如zbottom。5. 本篇常见错误排查5.1 菜单项顺序每次都不一样这是最常见的问题根因通常是同一 group 内没有指定数字。VS Code 对同一 group 内未指定顺序的项不保证稳定排序。解决办法就是给每个项加上1、2这样的后缀。5.2 group 写了但顺序没变检查group的值是否被引号包裹正确以及是否写在了view/item/context数组里而不是view/title里。两个贡献点的排序规则不通用。另外如果你修改了package.json但没有重新加载扩展开发宿主改动不会生效。按 CtrlR 重新加载窗口。5.3 when 条件里的正则不匹配viewItem ~ /^resource/这种写法要求contextValue确实以resource开头。如果你在getTreeItem里设置的是resource.dir那/^resource/能匹配如果设置的是myResource就匹配不上。建议在getTreeItem里打印一下contextValue或者用Developer: Inspect Context Keys确认。5.4 菜单项重复出现如果同一个command在view/item/context里配置了多次且when条件有重叠菜单里会出现重复项。检查是否有重复的配置块或者when条件是否过于宽松。5.5 分组名用了内置保留字navigation、1_、2_等是 VS Code 有特殊处理的分组名。如果你自定义的分组名和它们冲突排序行为可能不符合预期。建议自定义分组用有业务含义的前缀比如myext.sort1。5.6 排序在旧版本 VS Code 上不一致group的排序语法在较新版本中支持更好。如果你的插件需要兼容旧版本建议在engines.vscode里声明一个足够新的版本比如^1.80.0。同时在 README 里说明排序依赖的 VS Code 版本。排查完这些基本能覆盖 90% 的菜单顺序异常。如果还是不对把package.json里view/item/context的完整配置贴出来逐项对照上面的规则检查。6. 把排序规则用起来回到最开始的问题为什么zbottom会排到最后因为 group 名按字母升序z在字母表末尾。为什么sort1排在sort2前面因为后面的数字决定了同组内的顺序。这两条规则一旦记住菜单排序就不再是玄学。在实际开发中我建议把菜单项按功能分成三到四个 groupnavigation放高频操作operation放增删改sort放排序类操作zbottom放危险或低频操作。每个 group 内用1、2明确顺序。这样既符合用户的操作直觉也方便后续维护。如果你在开发过程中需要模型辅助生成命令或调试when条件可以用 TaoToken 的模型对话功能快速验证思路https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat 。对于需要长期做插件开发、频繁调用模型的场景Coding Plan 会更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan 。接入相关的文档都在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc 遇到配置问题可以先翻文档。最后留一个实用技巧在package.json里给每个菜单项加一行注释是不允许的JSON 不支持注释但你可以用command的命名来体现顺序比如favourite.sort.moveToTop、favourite.sort.moveUp这样在配置文件里从上到下读顺序一目了然。配合group的数字双重保险。
返回列表