我不知道的 VSCode 扩展:菜单与视图的魔法
引言
✨ 在上一篇文章中,我们一起迈出了 VSCode 扩展开发的第一步。现在,让我们继续深入探索,学习如何为你的扩展添加更丰富的用户界面元素,例如右键菜单、树视图 和 状态栏。这些元素能够极大地提升扩展的易用性和交互性,让你的扩展更加强大和用户友好。今天,就让我们一起揭开 VSCode 扩展中菜单与视图的魔法!
右键菜单 (Context Menu):指尖的魔法
🖱️ 右键菜单 (Context Menu),也称为上下文菜单,是用户界面中非常常见且实用的元素。通过右键点击,用户可以快速访问与当前上下文相关的操作。在 VSCode 扩展中,添加右键菜单可以极大地提升用户操作效率。
添加右键菜单
🧩 要为 VSCode 扩展添加右键菜单,我们需要在 package.json 文件中配置 menus contributes
{
"contributes": {
"menus": {
"editor/context": [ // 编辑器上下文菜单
{
"command": "extension.helloWorld", // 关联的命令
"group": "z_我的扩展", // 菜单分组,用于排序
"when": "editorFocus" // 菜单显示条件
}
],
"explorer/context": [ // 资源管理器上下文菜单
{
"command": "extension.myExplorerCommand",
"group": "navigation"
}
]
}
}
}
menus
: 定义菜单 contributes。editor/context
: 编辑器上下文菜单的位置。当用户在编辑器中右键点击时,会显示此菜单。explorer/context
: 资源管理器上下文菜单的位置。当用户在资源管理器中右键点击文件或文件夹时,会显示此菜单。command
: 指定点击菜单项时执行的命令 ID,需要提前在commands
contributes 中注册。group
: 菜单分组,用于控制菜单项在菜单中的排序位置。分组名称相同的菜单项会放在一起,并按照分组名称的字母顺序排序。通常使用数字_分组名称
的格式,例如1_编辑
,2_导航
,z_我的扩展
等。when
: 菜单项的显示条件,使用 When Clause Contexts 定义。例如,editorFocus
表示只有当编辑器获得焦点时才显示此菜单项。
示例:添加 "Hello World" 到编辑器右键菜单
📝 假设我们已经注册了一个命令 extension.helloWorld
(参考上一篇文章)。现在,我们想将这个命令添加到编辑器的右键菜单中。
-
修改
package.json
: 在contributes.menus.editor/context
中添加配置:{ "contributes": { "menus": { "editor/context": [ { "command": "extension.helloWorld", "group": "z_我的扩展", "when": "editorFocus" } ] } } }
-
重新加载扩展: 按下
Ctrl+Shift+P
(或Cmd+Shift+P
on macOS) 打开命令面板,输入Reload Window
并执行,重新加载 VSCode 窗口,使配置生效。 -
测试: 打开一个文件,在编辑器中右键点击,你将在右键菜单的 "z_我的扩展" 分组下看到 "Hello World" 菜单项。点击该菜单项,将会执行
extension.helloWorld
命令,弹出 "Hello World" 消息框。
树视图 (TreeView):结构化的信息展示
🌲 树视图 (TreeView) 是一种常用的用户界面组件,用于以树状结构展示层级数据。在 VSCode 扩展中,树视图非常适合展示文件目录、项目结构、自定义数据等信息。
添加树视图
🏗️ 要为 VSCode 扩展添加树视图,我们需要使用 viewsContainers
和 views
两个 contributes,在 package.json
文件中进行配置。
{
"contributes": {
"viewsContainers": { // 视图容器
"explorer": [ // 放置在资源管理器视图容器中
{
"id": "myTreeViewContainer", // 容器 ID
"title": "我的树视图", // 容器标题
"icon": "$(file-directory)" // 容器图标 (使用 VSCode 内置图标)
}
]
},
"views": { // 视图
"myTreeViewContainer": [ // 放置在 "myTreeViewContainer" 容器中
{
"id": "myTreeView", // 视图 ID
"name": "示例树视图", // 视图名称 (显示在视图标题栏)
"type": "tree", // 视图类型,固定为 "tree"
"command": "myTreeView.reveal" // (可选) 点击视图标题栏 "更多操作" 菜单时执行的命令
}
]
}
}
}
viewsContainers
: 定义视图容器。视图容器是树视图的载体,可以放置在 VSCode 侧边栏的不同位置,例如资源管理器 (explorer)、调试 (debug) 等。explorer
: 将视图容器放置在资源管理器视图容器中。id
: 视图容器的唯一 ID。title
: 视图容器的标题,显示在侧边栏。icon
: 视图容器的图标,可以使用 VSCode 内置图标,也可以使用自定义图标。VSCode 内置图标列表参考 Product Icon Reference。
views
: 定义视图。myTreeViewContainer
: 指定视图所属的视图容器 ID。id
: 视图的唯一 ID。name
: 视图的名称,显示在视图标题栏。type
: 视图类型,固定为"tree"
。command
: (可选) 点击视图标题栏 "更多操作" 菜单时执行的命令。通常用于 "Reveal in Explorer" 或 "Refresh" 等操作。
实现 TreeDataProvider
👨💻 仅在 package.json 中配置树视图是不够的,我们还需要提供树视图的数据。为此,我们需要实现 TreeDataProvider 接口,并将其注册到 VSCode。。
import * as vscode from 'vscode';
// 定义树视图的数据项类型
interface TreeItemData {
label: string;
children?: TreeItemData[];
}
// 实现 TreeDataProvider 接口
class MyTreeDataProvider implements vscode.TreeDataProvider<TreeItemData> {
private data: TreeItemData[];
constructor() {
this.data = [
{ label: 'Item 1', children: [{ label: 'Sub Item 1' }, { label: 'Sub Item 2' }] },
{ label: 'Item 2' },
{ label: 'Item 3', children: [{ label: 'Sub Item 3' }] }
];
}
getTreeItem(element: TreeItemData): vscode.TreeItem | Thenable<vscode.TreeItem> {
const treeItem = new vscode.TreeItem(element.label, element.children ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None);
return treeItem;
}
getChildren(element?: TreeItemData | undefined): vscode.ProviderResult<TreeItemData[]> {
if (!element) {
return this.data; // 根节点
}
return element.children; // 子节点
}
}
export function activate(context: vscode.ExtensionContext) {
// ...
// 注册 TreeDataProvider
const treeDataProvider = new MyTreeDataProvider();
vscode.window.registerTreeDataProvider('myTreeView', treeDataProvider);
}
TreeDataProvider<T>
: 接口,T
是树视图数据项的类型。getTreeItem(element: T)
: 返回指定数据项element
对应的TreeItem
对象。TreeItem
用于描述树视图的节点,包括标签、图标、展开状态等。getChildren(element?: T)
: 返回指定数据项element
的子节点数组。如果element
为undefined
,则返回根节点数组。
示例:创建简单的示例树视图
📝 按照上述步骤,我们创建了一个简单的示例树视图,展示了预定义的数据。
-
修改
package.json
: 添加viewsContainers
和views
contributes 配置 (参考上面的代码示例)。 -
实现
MyTreeDataProvider
: 创建MyTreeDataProvider
类并实现TreeDataProvider
接口 (参考上面的代码示例)。 -
注册
TreeDataProvider
: 在activate
函数中注册MyTreeDataProvider
。 -
重新加载扩展: 重新加载 VSCode 窗口。
-
查看树视图: 在 VSCode 侧边栏资源管理器视图容器中,你将看到名为 "我的树视图" 的容器,展开后可以看到 "示例树视图",其中展示了我们预定义的数据。
状态栏 (Status Bar):随时可见的信息展示
📢 状态栏 (Status Bar) 位于 VSCode 窗口底部,用于展示全局性的状态信息和提供快速操作入口。在 VSCode 扩展中,使用状态栏可以方便地向用户展示扩展的运行状态、重要信息,并提供常用的快捷操作。
创建和管理状态栏
🛠️ 要创建和管理状态栏,我们需要使用 vscode.window.createStatusBarItem()
方法。
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
// ...
// 创建状态栏项目
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
statusBarItem.text = "$( Smiley ) Hello Status Bar"; // 状态栏文本,可以使用 VSCode 内置图标
statusBarItem.tooltip = "This is a status bar item"; // 鼠标悬停提示
statusBarItem.command = "extension.helloWorld"; // 点击状态栏项目时执行的命令
statusBarItem.show(); // 显示状态栏项目
context.subscriptions.push(statusBarItem); // 将状态栏项目添加到 context.subscriptions,以便在插件卸载时自动销毁
}
vscode.window.createStatusBarItem(alignment, priority)
: 创建状态栏项目。alignment
: 状态栏项目在状态栏中的对齐方式,vscode.StatusBarAlignment.Left
(左对齐) 或vscode.StatusBarAlignment.Right
(右对齐)。priority
: 状态栏项目的优先级,数字越小优先级越高,优先级高的项目会更靠近状态栏的边缘显示。
statusBarItem.text
: 状态栏显示的文本。可以使用纯文本,也可以使用 VSCode 内置图标,例如$( Smiley )
表示笑脸图标。statusBarItem.tooltip
: 鼠标悬停在状态栏项目上时显示的提示文本。statusBarItem.command
: 点击状态栏项目时执行的命令 ID。statusBarItem.show()
: 显示状态栏项目。context.subscriptions.push(statusBarItem)
: 将状态栏项目添加到context.subscriptions
,VSCode 会在扩展卸载时自动销毁这些资源,避免内存泄漏。
示例:创建简单的状态栏项目
📝 按照上述步骤,我们创建了一个简单的状态栏项目,显示文本和图标,并关联了一个命令。
-
在
activate
函数中创建状态栏项目: 使用vscode.window.createStatusBarItem()
创建状态栏项目,并设置text
,tooltip
,command
等属性 (参考上面的代码示例)。 -
显示状态栏项目: 调用
statusBarItem.show()
方法显示状态栏项目。 -
添加到
context.subscriptions
: 将状态栏项目添加到context.subscriptions
。 -
重新加载扩展: 重新加载 VSCode 窗口。
-
查看状态栏: 在 VSCode 窗口底部状态栏的右侧,你将看到我们创建的状态栏项目,显示 "😊 Hello Status Bar"。鼠标悬停时显示提示 "This is a status bar item"。点击状态栏项目,将会执行
extension.helloWorld
命令。
总结
🎉 恭喜你,又掌握了 VSCode 扩展开发的两个重要技巧:添加右键菜单 和 创建树视图,以及如何使用 状态栏 展示信息。通过灵活运用这些技巧,你可以为你的 VSCode 扩展打造更加完善的用户界面,提升用户体验。在下一篇文章中,我们将继续探索 VSCode 扩展的更多高级功能,例如 Webview 和 Output Channel,敬请期待!