上一遍博客介绍了如何从0到1搭建vscode插件开发的base code,这遍博客将重点介绍如何配置menu。通常,开发一款插件,会将插件显示在VSCode 左侧的活动栏(Activity Bar),那么如何配置让插件显示在Activity Bar中呢?非常简单。在package.json中增加如下的内容即可。
SideBar配置
"viewsContainers": {
"activitybar": [
{
"id": "demo",
"title": "demo",
"icon": "./public/static/bot.png"
}
]
},
"views": {
"demo": [
{
"type": "webview",
"id": "demoSidebar",
"name": "DemoSidebar"
}
]
},
activitybar配置的作用:在 VSCode 左侧的活动栏(Activity Bar)中添加一个新的视图容器。提供一个名为 "demo" 的新图标,当用户点击这个图标时,可以打开相关的视图面板.
views配置的作用:在 "demo" 视图容器中添加一个类型为 webview 的视图,名为 "demoSidebar"。需要注意:views里面的名称要与视图容器中定义的id保持一致。
配置了上面的内容后,如果要正常显示,还需要修改extension.ts的内容,extension.js中内容如下所示:下面的代码创建了一个WebviewViewProvider的class,通过resolveWebviewView方法来创建插件的UI界面。在activate方法中,再通过vscode.window.registerWebviewViewProvider将provider注册进去。
import * as vscode from 'vscode';
import * as path from 'path';
class MyWebviewViewProvider implements vscode.WebviewViewProvider {
public static readonly viewName = 'demoSidebar';
constructor(private readonly _extensionPath: string) { }
public resolveWebviewView(
webviewView: vscode.WebviewView,
context: vscode.WebviewViewResolveContext,
_token: vscode.CancellationToken
) {
webviewView.webview.options = {
enableScripts: true,
localResourceRoots: [vscode.Uri.file(path.join(this._extensionPath, 'dist'))]
};
const onDiskPath = vscode.Uri.file(
path.join(this._extensionPath, 'dist', 'bundle.js')
);
const webviewUri = webviewView.webview.asWebviewUri(onDiskPath);
webviewView.webview.html = this.getWebviewContent(webviewUri);
}
private getWebviewContent(webviewUri: vscode.Uri): string {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Taoli Webview</title>
</head>
<body>
<div id="root"></div>
<script src="${webviewUri}"></script>
</body>
</html>`;
}
}
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.window.registerWebviewViewProvider(
MyWebviewViewProvider.viewName,
new MyWebviewViewProvider(context.extensionPath)
)
);
}
export function deactivate() { }
上面构建html代码时,需要注意一点:在<body></body>中要添加上<div id="root"></div>的代码,否则UI无法显示,会提示无法找到root element的错误。因为在用React构建UI时,增加了查看root element的逻辑。下面是react构建的index.tsx文件。
const App = () => {
return (
<div>
<input type="text" name="name"></input>
<button>hello</button>
</div>
);
};
const rootElement = document.getElementById('root');
if (rootElement) {
const root = (ReactDOM as any).createRoot(rootElement);
root.render(<App />);
} else {
console.error('Root element not found!');
}
配置完成后,再次开启extension,可以看到在sidebar中显示了插件UI,具体如下图所示:
上面介绍了如何在sidebar中显示插件的UI,接着在看看如何在配置右键菜单,通过右键菜单,可以trigger相关的command。
配置右键菜单
下面的配置中,首先定义一个子菜单 demo.submenu,并命名为 "Demo"。接着,在编辑器的右键上下文菜单中添加一个子菜单 demo.submenu。使用户在右键点击编辑器中的内容时,可以方便地访问 "Demo" 相关的命令.在 demo.submenu 子菜单中添加 demo.showOne 和 demo.showTwo 命令,将相关的命令放入子菜单中,方便用户选择和执行这些命令.
"contributes": {
"commands": [
{
"command": "demo.showOne",
"title": "showOne"
},
{
"command": "demo.showTwo",
"title": "showTwo"
}
],
"submenus": [
{
"id": "demo.submenu",
"label": "Demo"
}
],
"menus": {
"editor/context": [
{
"submenu": "demo.submenu",
"group": "demo"
}
],
"demo.submenu": [
{
"command": "demo.showOne"
},
{
"command": "demo.showTwo"
}
]
}
},
配置完后,启动extension,在打开的文件中,点击右键,可以看到新配置的两个菜单。具体如下图所示:
如果要验证点击菜单是否有效,可以在extension.ts中对showOne和showTwo两个命令配置简单的信息显示即可。具体内容如下所示,修改extension.ts,再次运行,点击菜单后,在窗口中就会显示对应的信息。
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.window.registerWebviewViewProvider(
MyWebviewViewProvider.viewName,
new MyWebviewViewProvider(context.extensionPath)
)
);
context.subscriptions.push(
vscode.commands.registerCommand('demo.showOne', () => {
vscode.window.showInformationMessage('I am showOne.');
})
);
context.subscriptions.push(
vscode.commands.registerCommand('demo.showTwo', () => {
vscode.window.showInformationMessage('I am showTwo.');
})
);
}