vscode插件开发
本文的目的是总结vscode
的插件开发入门,之前一直以为开发插件是一件很难的事情,后来工作上需要搞一个效率小工具,就试着找了些资料来入门,发现其实就入门和开发一些简单功能的插件来说难度还是很低的。因为vscode
本身是基于electron
开发的,所以总体来说开发插件就是在写node
代码,额外再加一些编辑器api
,插件发布的过程和npm
包的发布很类似。vscode
官方提供的脚手架还帮忙加上了调试配置,调试非常方便。下面就来说下具体步骤,在学习的过程中参考了一些博客,放在了最后面。
环境准备
这个很简单,我就直接拷贝过来了。
nodejs
: 建议使用LTS
版本npm
: 建议最新版本yeoman
:npm install -g yo
generator-code
:npm install -g generator-code
另外小TIPS
,我们平时直接安装的插件所在目录是~/.vscode/extensions
,有兴趣的可以看看这些插件是怎么实现的。
脚手架
安装的yo
可以直接生成一个Hello World
版本的插件目录。执行
1
|
yo code
|
即会提示一些问题,按照个人喜好填写即可,最后会生成样板代码:
1
|
.
|
其中的quickstart.md
是新手引导,里面包含了对文件的作用解析、如何运行插件、测试插等等,推荐去看一看,我们在下面也会介绍一些。除此之外在package.json
里也包含了很多非常重要的信息:
1
|
{
|
启动、调试插件
启动运行
脚手架生成的其实就是一个node
应用,直接按F5
即可运行。对配置感兴趣的也可以查看根目录下的.vscode/launch.json
。
跑起来以后默认会新开一个vscode
窗口,然后会发现什么都没有发生,这是由插件的启动方式决定的,配置于package.json
里的activationEvents
项。常用的有:
onLanguage
在打开特定语言类型的文件后激活onCommand
在执行特定命令后激活
由于我们的插件是配置的onCommand
启动,并且指定的命令名是Hello World
,所以我们在新开的vscode
窗口中按下快捷键Command+Shift+P
后再找到Hello World
,选中并执行即可。
最后顺利的话,编辑器右下角会弹出Hello World!
。
如果细心的话,还会在源窗口的控制台的调试控制台
tab 中看到如下输出:
1
|
Congratulations, your extension "hello-world" is now active!
|
这个就是由插件的真正代码部分输出的了。我们接下来看看extension.js
的内容:
extension.js
1
|
// vscode编辑器api入口
|
以上就是此插件的完整逻辑了,配置注释是很简单的。可以看到主要就是两个生命周期函数,另外搭配一些编辑器api
就完成了。
调试
脚手架已经贴心的帮我们加了调试配置,我们只用添加断点即可:
Command 配置
上面提到了生成一个command
只需要 2 步,先是利用vscode.commands.registerCommand
注册一个,然后再到package.json
里的contributes.commands
中配置即可。围绕command
还可以做一些其他事情,最常见的就是配置右键菜单和快捷键。
右键菜单
表示右键的菜单里出现指定command
,配置方法:
1
|
"contributes":{
|
快捷键
有了快捷键后,就不用每次在命令面板里查找并运行命令了,同样是在package.json
中配置:
1
|
"contributes": {
|
发布
主要参考的是官方文档
首先需要安装vsce
工具:
1
|
npm install -g vsce
|
本地打包
将插件打包成.vsix
文件。
1
|
vsce package
|
会在项目根目录生成hello-world-0.0.1.vsix
,然后在编辑器的插件面板选择从VSIX安装
即可:
发布到插件市场
-
需要获取一个
token
,参考官方文档 -
利用
token
创建一个publisher
,这是在插件市场的用户
1
|
vsce create-publisher (publisher name)
|
- 本地登录此用户
1
|
vsce login (publisher name)
|
- 发布插件
1
|
vsce publish
|
顺利的话在控制台会提示发布成功,然后过几分钟就可以在插件市场搜到自己的插件啦!😄
版本升级
当插件内容发生变更时,重新发布时最好更新版本号,vsce
可以遵循语义化版本指定升级大(major
)/小(minor
)/补丁(patch
)版本,也可以直接指定版本号。例如只升级小版本:
1
|
vsce publish minor
|
如果插件代码在gitlab
上,因为仓库在内网,需要事先将README
里的图片替换为公网cdn
上的路径。
snippets
snippets
是代码片段,可以理解为代码快捷键,在输入很少量触发代码后即可联想出一大坨关联代码,非常方便。对于js
、ts
、vue
都可以在插件市场找到非常多的snippets
插件。
开发snippets
只用两步:
- 编写
snippets
映射文件,它是一个json
,例如javascript.json
:
1
|
{
|
- 在
package.json
中配置
1
|
"contributes": {
|
最后就可以在编辑器看到效果了:
更多细节参考snippets-syntax
插件默认配置
很多插件是需要一些额外配置才能工作的,设置默认配置同样在package.json
里:
1
|
"contributes": {
|
默认配置是json schema
格式,在覆盖默认配置时如果校验出错会有提示。
插件中使用getConfiguration
来读取配置:
1
|
function getConfig() {
|
监听配置项修改
在用户安装了插件后,可能会修改配置,如何实时监听配置项的修改呢? vscode
提供了onDidChangeConfiguration
事件监听。
1
|
vscode.workspace.onDidChangeConfiguration(function(event) {
|
常见编辑器 api
所有vscode
相关api
都可以在官网文档查找,vscode
内部也集成了.d.ts
文件,编辑器内直接跳转定义即可。这里只列举一些常见的api
.
messgae
用于展示提示性消息,出现在编辑器右下角,而不是顶部或右上角。
和console
类似,提供了普通消息、警告消息、错误消息。
1
|
vscode.window.showInformationMessage('普通消息');
|
消息也支持交互按钮,当选中按钮时返回的是按钮本身:
1
|
vscode.window.showErrorMessage(`与starling的远程交互依赖vscode-starling.sid配置项`, '打开配置项').then(selection => {
|
input box
在编辑器顶部展示一个input
输入框,使用vscode.window.showInputBox
,会返回一个Promise
:
1
|
const text: string | undefined = await vscode.window.showInputBox({
|
quick pick
用于从一组选项中选择一个,类似于select
组件。使用vscode.window.showQuickPick
,同样返回一个Promise
,resolve
时得到被选中的选项或undefined
:
1
|
const lang: string | undefined = await vscode.window.showQuickPick(['en', 'zh', 'ja'], {
|
每个选项也可以是对象类型:
1
|
const option: Object | undefined = await vscode.window.showQuickPick([{ id: 1, name: 'a' }, { id: 2, name: 'b' }, { id: 3, name: 'c' }], {
|
output channel
在利用Control + ~
打开控制台后,会出现 4 个tab
,从左到右依次是问题
、输出
、调试控制台
、终端
。output channel
就是用于控制输出
tab
的内容,可以往其中追加文本、追加行、清空,可以将其看成一个简单的文件。output channel
适用于一次展示大量信息.
使用vscode.window.createOutputChannel
创建output channel
实例,然后就可以操作各种api
了。
1
|
const opc = vscode.window.createOutputChannel('textSearch'); // 可以有多个OutputChannel共存,使用参数名区分
|
一个例子:
file selector
有些时候需要操作本地文件系统,例如选择某个文件、将文件保存到指定位置等。
保存文件到指定位置
使用showSaveDialog
,它会打开文件选择器弹窗,选择了保存路径后点击确定会返回选中的路径,如果点击取消会返回undefined
。
1
|
// 让用户手动选择文件的的存储路径
|
文件选择
showOpenDialog
同样会打开文件选择器弹窗,不过这次是用于选择文件,如果有选择文件会返回选中的文件路径,反之返回undefined
。
1
|
// showOpenDialog返回的是文件路径数组
|
hover
有时候需要在hover
到文本上时展示一些提示信息,例如eslint
插件在hover
到不合规的代码上时会展示具体违反了哪些规则:
处理hover
需要注册一个hover
处理器,vscode
会在hover
到文本上时自动调用处理器,同时传递hover
相关的信息。例如一个展示光标所在的单词hover
处理器:
1
|
/**
|
selection
与hover
类似,有时候需要处理选中的文本,获取它是通过vscode.TextEditor
实例上的属性,有两个相关属性
selections
:所有被选中的文本信息selection
:第一个被选中的文本信息, 等同于selections[0]
获取TextEditor
的一个方法是通过注册textEditorCommand
,会在回调函数里提供TextEditor
实例,例如展示选中文本:
1
|
let command = vscode.commands.registerTextEditorCommand('extension.selection', function(textEditor, edit) {
|
FileSystemWatcher
用于监听文件是否发生了变化,可以监听到新建、更新、删除这 3 种事件,也可以选择忽略其中某个类型事件。创建watcher
是利用vscode.workspace.createFileSystemWatcher
:
1
|
function createFileSystemWatcher(globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher;
|
例如监听所有js
文件的变动:
1
|
const watcher = vscode.workspace.createFileSystemWatcher('*.js', false, false, false);
|