NEWS LETTER

VS Code 插件开发指北 (一)

  • Home
  • vscode_extension
Scroll down

最近闲来无事,给公司框架做了开发代码片段提示和一些常用工具整合的插,在这里记录一下踩过的坑和一些常用的基本功能示例。

插件能做什么

因为 VS Code 是基于 Electron 的,所以一般 node 能做的一般基本上都是可以是现实。如果你想对 VS Code 做些个性化的配置,你可以开发自定义主题、图标主题、欢迎页面、自定义左侧的面板(例如资源管理器栏那种)等。你还可以自己定义命令、快捷键、自动补全、菜单等来提升你的开发效率。甚至你可以对现有语言做扩展或者定义新的语言的支持。

创建插件项目

首先安装官方的脚手架

1
2
3
4
5
6
// 安装脚手架
npm install -g yo generator-code

// 创建项目
yo code
// 会一路提示你 输入插件名 插件id 等等。根据需要填写

微软提供了两种方式去开发,一种是 JavaScript 和 TypeScript 去开发,可以根据自己的习惯选择。创建好后按 F5 会打开调试用的 VS Code 窗口来调试插件

使用 JavaScript 生成的项目结构,
├── .vscode
│ ├── launch.json // 插件加载和调试的配置
│ └── tasks.json // 配置TypeScript编译任务
├── .gitignore // 忽略构建输出和node_modules文件
├── README.md // 插件文档
├── CHANGELOG.md // 插件更新日志
├── extension.ts // 插件源代码
├── package.json // 插件配置清单
├── jsconfig.json //

先看下入口文件,入口文件需要导出两个函数 activate 和 deactivate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//extension.js 文件

// 插件激活调用,也是插件的入口
function activate(context) {
console.log('Congratulations, your extension "vscode-demo" is now active!');

// 注册一个命令
let disposable = vscode.commands.registerCommand('vscode-demo.helloWorld', function () {
//命令触发是调用
vscode.window.showInformationMessage('Hello World from vscode-demo!');
});

context.subscriptions.push(disposable);
}

// 插件销毁调用
function deactivate() {}

module.exports = {
activate,
deactivate
}

这个初始化插件项目,默认就是注册了个 hello world 命令,然后运行命令显示 hello world 的通知,按F5运行项目,在命令面板输入 hello world,可以看到右下角弹出通知
项目结构
项目结构

配置说明

vscode 插件的 package.json 是 npm 的一个超集,插件的图标、命令注册、菜单配置、语言注册、主题注册、代码片段等一系列的都需要在这个文件里配置。

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
// package.json

{
"name": "vscode-demo",
"displayName": "vscode-demo",
"description": "",
"version": "0.0.1",
"publisher": "", //发布者id,后面会讲怎么发布到插件市场
"engines": { //vscode 最低版本
"vscode": "^1.57.0"
},
"categories": [ //插件市场的分类 可以设置成语言主题等其他类型
"Other"
],
"activationEvents": [ //扩展的激活事件
"onCommand:vscode-demo.helloWorld", //调用命令时激活
"onLanguage:python", //py时激活插件
"workspaceContains:**/.editorconfig",// 文件夹打开时激活
"onDebug",//调试前激活
...
"*" //启动时候激活,使用这个不需要设置其他的
],
"main": "./extension.js", //指定插件入口文件
"icon": "", //插件图标
"contributes": { //大部分的配置都要在这里配置
"commands":[], //配置命令,如果需要暴露给用户使用的需要在这里配置
"menus":[], //配置菜单
"submenus":[], //配置子菜单会用到
"languages": [], //配置语言
"grammars":[], //为语言配置TextMate语法
"keybindings":[], //配置快捷键
"snippets":[], //配置代码片段
"themes":[], //配置主题
"views":[], //配置活动栏视图
"viewsWelcome":[], //配置左侧视图欢迎页
"viewsContainers":[], //配置视图容器
"configuration":{}, //配置插件配置
"configurationDefaults":{}, //配置插件默认配置
"colors":{},
"problemMatchers":{},
"taskDefinitions":{},
"typescriptServerPlugins":{}
},
}

命令示例

一般提供给被人使用的功能都是通过命令注册,在命令的回调函数里处理相关功能逻辑,然后就可以在 VS Code 的命令面板调用相关命令。你也可以注册快捷键、菜单等和命令绑定在一起来触发命令。VS Code 内部含有大量和编辑器交互、控制UI、后台操作的内置命令给我们使用。

注册命令

vscode 在 commands 下提供了 registerCommandregisterTextEditorCommand用来注册命令,registerTextEditorCommand 注册的命令只会在编辑器激活的时候才调用。

1
2
3
4
5
6
7
8
9
10
11
// 在activate函数注册命令

context.subscriptions.push(
// 第一个参数为命令ID,第二次参数命令回调函数
vscode.commands.registerCommand('vscode-demo.currentText', function () {
// 获取当前激活的编辑器
let currentEditor = vscode.window.activeTextEditor;
// 获取编辑器选择的内容
console.log(currentEditor.document.getText(currentEditor.selection));
})
);

命令注册后默认是不会对外提供的,如果需要提供给用户使用还需要在 package.jsoncontributes.commands 添加相应配置

1
2
3
4
5
6
7
8
9
10
11
// package.json
{
"contributes": {
"commands": [
{
"command": "vscode-demo.currentText",
"title": "获取选择文本"
}
]
}
}

按住 F5 运行插件,在命令面板输入 获取选择文本 ,会发现报错了。是因为 activationEvents 配置里只配置了 “onCommand:vscode-demo.helloWorld” 才会激活插件,我们需要把新加的命令也加入进去,或者改为 *

1
2
3
4
// package.json
{
activationEvents: [ "*" ]
}

执行命令

在 commands 提供了 executeCommand API用来调用命令,可以使用它调用我们插件里的命令,也可以调用 VS Code 内置的命令。
使用示例

1
2
// 调用
vscode.commands.executeCommand('vscode-demo.helloWorld')

菜单示例

package.json 中的 contributes.menus 用来的配置菜单项,下面这些编辑器可以配置菜单的地方。

  • 全局命令面板 - commandPalette
  • 资源管理器上下文菜单 - explorer/context
  • 编辑器上下文菜单 - editor/context
  • 编辑器标题栏 - editor/title
  • 编辑器标题上下文菜单 - editor/title/context
  • 调试栈视图的上下文菜单 - debug/callstack/context
  • 视图的标题菜单 - view/title
  • 视图项的菜单 - view/item/context
  • SCM 标题菜单 - scm/title
  • SCM 资源组 - scm/resourceGroup/context
  • SCM 资源 - scm/resource/context
  • SCM 改变标题 - scm/change/title

配置菜单需要提供,选中菜单时执行的命令和菜单出现的条件。

1
2
3
4
5
6
7
8
{
"command": "命令",
"when": "条件",
"alt": "可选命令",
"group": "菜单分组",
"submenu": "配置二级菜单",
"icon": "图标"
}

控制命令面板的命令

默认情况下注册的命令都会显示在命令面板中,有时候需要更具条件显示,就可以在 commandPalette 配置指定命令然后通过 when 控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// package.json
{
"contributes": {
"commands": [
{
"command": "vscode-demo.currentText",
"title": "获取选择文本"
}
],
"menus": {
"commandPalette": [
{
"command": "vscode-demo.currentText",
"title": "获取选择文本",
"when": "editorHasSelection" // 只有选择文本才显示
}
]
}
},
}

when 条件

when 提供的逻辑操作符有 ==、!=、||、&&、!、=~(正则)、>、>=、<、<=、in 等操作符,和js的类似,多了一个 =~ 符匹配正则。VS Code 还提供了很多上下文可以和这些操作符组合使用。查看上下文详情
示例

1
2
3
"when":"resourceExtname != .js" //不是js文件时
"when":"editorHasSelection" //选择文本才显示
"when":"!editorHasSelection" //不选择文本才显示

配置多级菜单

使用 submenu 指定父级菜单的ID,submenus 配置父级菜单名称等信息。

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
{
"contributes": {
"menus": {
"editor/context": [
{
"command": "vscode-demo.currentText"
},
{
"submenu": "first.menu"
}
],
"first.menu": [
{
"command": "vscode-demo.currentText"
},
{
"submenu": "two.menu"
}
],
"two.menu": [
{
"command": "vscode-demo.currentText"
}
],
},
"submenus": [
{
"id": "first.menu",
"label": "一级菜单"
},
{
"id": "two.menu",
"label": "二级菜单"
}
]
},
}

示例

分组排序

菜单项可以通过组来分类。根据下列默认规则,然后按照字母排序,

  • 编辑器上下文菜单(editor/context)默认有这些分组:
    • navigation - navigation组始终在最上方。
    • 1_modification - 紧接上一个组,这个组包含可以修改你代码的命令。
    • 9_cutcopypaste - 然后是基础编辑命令。
    • z_commands - 最后一个分组则是命令面板入口。
  • 资源管理器上下文菜单(explorer/context)默认有下列分组:
    • navigation - 在VS Code 中导航的相关命令。navigation 组始终在最上方。
    • 2_workspace - 和工作区操作相关的命令。
    • 3_compare - 比较文件和diff相关的命令。
    • 4_search - 在搜索视图中和搜索相关的命令。
    • 5_cutcopypaste - 和剪切、复制、粘贴文件相关的命令。
    • 7_modification - 修改文件的相关命令。
  • 编辑器标签菜单默认有下列分组
    • 1_close - 和关闭编辑器相关的命令。
    • 3_preview - 和固定编辑器相关的命令。
  • 编辑器标题栏(editor/title)的默认分组
    • 1_diff - 与使用差异编辑器相关的命令。
    • 3_open - 与打开编辑器相关的命令。
    • 5_close - 与关闭编辑器相关的命令。

组内的菜单顺序取决于标题或者序号属性。菜单的组内顺序由@加到 group 值的后面得以确定:

1
2
3
4
5
"editor/title": [{
"when": "editorHasSelection",
"command": "extension.Command",
"group": "myGroup@1"
}]

注册快捷键

快捷键还是比较简单的,Windows 和Linux 是 key 指定,macOS 使用 mac 指定的快捷键。

1
2
3
4
5
6
7
8
"contributes": {
"keybindings": [{
"command": "vscode-demo.currentText", //快捷键绑定命令
"key": "ctrl+f1",
"mac": "cmd+f1",
"when": "editorHasSelection" // 出现时机
}]
}

设置好后,使用了对应命令的菜单项也会显示对应快捷键,如图所示
示例

我很可爱,请给我钱

其他文章
cover
VS Code 插件开发指北 (二)
  • 21/06/17
  • 20:19
  • 记录类
cover
Flutter 中的动画
  • 21/04/28
  • 15:04
  • 记录类
目录导航 置顶
  1. 1. 插件能做什么
  2. 2. 创建插件项目
  3. 3. 配置说明
  4. 4. 命令示例
    1. 4.1. 注册命令
    2. 4.2. 执行命令
  5. 5. 菜单示例
    1. 5.1. 控制命令面板的命令
    2. 5.2. when 条件
    3. 5.3. 配置多级菜单
    4. 5.4. 分组排序
  6. 6. 注册快捷键
请输入关键词进行搜索