vscode插件和源码通过命令进行通信

本文讲述一下vscode插件和源码通过命令进行通信

原文链接:https://zhouhangzooo.github.io/2019/04/10/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>
        οnclick="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时
```
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所有快捷键的功能我们都可以通过执行命令来实现。

原文链接:https://zhouhangzooo.github.io/2019/04/10/vscode插件与源码通信/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值