vscode插件调用源码功能

本文讲述一下vscode插件和源码通过命令进行通信
在之前”vscode插件与webview相互通信”文章中,讲述webview和插件进行通信,里面有个注册命令,之前文章没有详细代码,其实代码vscoode官网都有,

接下来要说命令,那么先贴一下注册命令的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
context.subscriptions.push(vscode.commands.registerCommand('extension.demo.openWebview', function (uri) {
//这个uri就是传递过来的参数,无论是vscode插件和webview通信还是vscode插件和vscode源码通信都可以通过这个进行数据传递
if (flag) { //判断flag让webview不重复打开
if(value == undefined) { //如果是第一次打开课程
value = uri;
panel.webview.postMessage({ command: "course_id",text: value});
}
else if (value != undefined && value == uri) { //如果重复点击
return;
}else {
value = uri;
panel.webview.postMessage({ command: "course_id",text: value });
}
return;
}
value = uri;
panel = vscode.window.createWebviewPanel(
'testWebview', // viewType
"课程提示", // 视图标题
2, // 显示在编辑器的哪个部位
{
enableScripts: true, // 启用JS,默认禁用
retainContextWhenHidden: true, // webview被隐藏时保持状态,避免被重置
enableFindWidget: true,
}
);

flag = true;

panel.webview.html = getWebViewContent(context, 'src/test-webview.html');
//发送消息到webview
if (value !== undefined && value !== "") {
panel.webview.postMessage({ command: value });
}
panel.webview.onDidReceiveMessage(message => {
//接收命令
switch (message.command) {

case 'openHint':
vscode.window.showInformationMessage(message.text, {
modal: true
});
break;
}

}, undefined, context.subscriptions);

//当webview被关闭时,设置标识,就可以重新打开webview
panel.onDidDispose(
() => {
flag = false;
console.log('===============================close-webview');
}, null, context.subscriptions);

}));

function getWebViewContent(context, templatePath) {
const resourcePath = util.getExtensionFileAbsolutePath(context, templatePath);
const dirPath = path.dirname(resourcePath);
let html = fs.readFileSync(resourcePath, 'utf-8');
// vscode不支持直接加载本地资源,需要替换成其专有路径格式,这里只是简单的将样式和JS的路径替换
html = html.replace(/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g, (m, $1, $2) => {
return $1 + vscode.Uri.file(path.resolve(dirPath, $2)).with({
scheme: 'vscode-resource'
}).toString() + '"';
});
return html;
}

webview页面

1
2
3
4
5
6
7
8
9
10
11
<script>
window.addEventListener('message', event => {
const message = event.data;
if(message.command != "course_id")
{
return;
}
courseId = message.text;
// console.log("==================================courseId" + courseId);
});
</script>
<div>
    onclick="openHint()"
</div>
1
2
3
4
5
6
function openHint() {
vscode.postMessage({
command: 'openHint',
text: '试着输入 helloword '
})
}

可以看到上面的代码,其实和官方差不多,上面代码是注册了命令,通过命令打开webveiw,其实就是打开了src目录下的test-webview.html页面,这个html我们可以自定义,同时页面可以传输数据到这里然后panel.webview.onDidReceiveMessage接收并处理。

当我们想要传输数据到webivew时

1
vscode.commands.executeCommand("extension.demo.openWebview","需要传输的数据");

这样通过命令我们就可以将数据传输到webview页面上了,那么我们试试和源码进行交互

思考:源码中肯定有实现新建文件,而它给我们提供快捷键Ctrl+N打开,所以vscode源码中肯定有一个新建文件的命令,我们只需执行它,便可以新建文件

根据我的研究,源码的功能,绝大部分源码实现方法在XXService.ts中,而你想要调用它,那么方法在XXActions.ts中。
我们查看一个例子:fileActions.ts文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export class GlobalNewUntitledFileAction extends Action {
public static readonly ID = 'workbench.action.files.newUntitledFile';
public static readonly LABEL = nls.localize('newUntitledFile', "New Untitled File");

constructor(
id: string,
label: string,
@IEditorService private readonly editorService: IEditorService
) {
super(id, label);
}

public run(): Promise<any> {

return this.editorService.openEditor({ resource: resources.joinPath(lastDir, untitledFileName), options: { pinned: true } } as IUntitledResourceInput); // untitled are always pinned

}

public run(): Promise<any> {
return this.editorService.openEditor({ options: { pinned: true } } as IUntitledResourceInput); // untitled are always pinned
}
}

上面是vsocde源码中代码,可以看到最终运行run即可新建文件,我们一步步找,可以看到官方调用run方法是通过actions.ts文件中的接口方法,通过一个参数继承这个接口,然后参数调用里面的方法实现的。

1
2
3
4
5
export interface IActionRunner extends IDisposable {
run(action: IAction, context?: any): Promise<any>;
onDidRun: Event<IRunEvent>;
onDidBeforeRun: Event<IRunEvent>;
}

而我们如果想要在插件中实现新建文件,那么我们只需要执行命令即可,命令就是XXAction的id,比如新建文件的命令就是GlobalNewUntitledFileAction.ID

1
2
import * as vscode from "vscode";
vscode.commands.executeCommand('workbench.action.files.newUntitledFile');

因此,vscode所有快捷键的功能我们都可以通过执行命令来实现。

文章目录
  1. 1. 接下来要说命令,那么先贴一下注册命令的代码
  2. 2. webview页面
  3. 3. 当我们想要传输数据到webivew时
  4. 4. 思考:源码中肯定有实现新建文件,而它给我们提供快捷键Ctrl+N打开,所以vscode源码中肯定有一个新建文件的命令,我们只需执行它,便可以新建文件