VSCode插件开发
package.json
contributes
之前说到 package.json 是 vscode 扩展的清单文件,里面有很多字段,在这个文件中,activationEvents、main 以及 contributes,是文件中非常重要的部分。
contributes 是在 package.json 中的一组 JSON 声明,是 package.json 中重要的内容,有很多重要的配置项,下面罗列一些比较常见的配置项。
configuration
插件配置项。
javascript
{
"contributes": {
// 插件配置项
"configuration": {
// 配置项标题,会显示在vscode的设置页
"title": "vscode-plugin-demo",
"properties": {
// 举个例子,配置昵称
"vscodePluginDemo.yourName": {
"type": "string",
"default": "guest",
"description": "你的名字"
},
}
}
}
}
其中详细的配置项有:
-
title
标题,插件的名称
-
properties
属性,配置的 key 将用于命名空间和构造标题,会根据 key 中层次结构进行分组。
javascript
// 例如
gitMagic.blame.dateFormat
// 生成的标题是
Blame: Date Format
-
description
描述,描述出现在标题之后和输入字段之前,布尔值除外,其中描述用作复选框的标签
-
type
类型,number、string、boolean 可以直接在 settings UI 中编辑,boolean 将会作为复选框的标签
-
default
定义属性的默认值
-
minimum / maximum
限制数值的最大值和最小值
-
maxLength / minLength
限制字符串长度
-
pattern
使用正则限制字符串
-
maxItems / minItems
限制数组长度
-
scope
范围
属性值
application:适用于所有 VScode 实例的设置,只能在用户设置中设置
machine:在用户或远程设置中设置的机器特定设置
machine-overridable:可以被工作区或者文件夹设置的机器特定设置
window:可以在用户、工作区或远程设置中配置的 windows 特定设置
resource:适用于文件和文件夹的资源设置,可以在所有设置级别进行设置,甚至文件夹设置
language-overridable:可以在语言级别覆盖的资源设置
configurationDefaults
默认配置。
javascript
{
"contributes": {
"configurationDefaults": {
"[markdown]": {
"editor.wordWrap": "on",
"editor.quickSuggestions": false
}
}
}
}
commands
由 title、icon(可选)、category、command 命令组成。默认情况下,命令显示在命令面板中,但它们也可以显示在其他菜单中。
当调用命令时,VS Code 将发出 activationEvent onCommand:${command}
javascript
{
"contributes": {
"commands": [
{
"command": "extension.sayHello",
"title": "Hello World",
"category": "Hello",
"icon": {
"light": "path/to/light/icon.svg",
"dark": "path/to/dark/icon.svg"
}
}
]
}
}
menus
菜单项。
javascript
{
"contributes": {
"menus": {
"editor/title": [
{
// 通过 when 来控制何时可见
"when": "resourceLangId == markdown",
// 定义菜单被点击后要执行什么操作
"command": "markdown.showPreview",
// 定义备用命令,按住alt键打开菜单时将执行对应命令
"alt": "markdown.showPreviewToSide",
// 定义菜单分组 通过 @<number> 附加到组内来指定的
"group": "navigation"
}
]
}
}
}
- editor/title 是 key 值,定义了这个菜单出现在哪里,比较常见的是 explorer/context 和 editor/context
还可以选择的拓展项有:
拓展项 | 名称 |
---|---|
全局命令面板 | commandPalette |
资源管理器上下文菜单 | explorer/context |
编辑器上下文菜单 | editor/context |
编辑器标题菜单栏 | editor/title |
编辑器标题上下文菜单 | editor/title/context |
调试调用堆栈视图上下文菜单 | debug/callstack/context |
调试调用堆栈视图内联操作 | debug/callstack/context group inline |
调试变量视图上下文菜单 | debug/variables/context |
调试工具栏 | debug/toolbar |
SCM 标题菜单 | scm/title |
SCM 资源组菜单 | scm/resourceGroup/context |
SCM 资源文件夹菜单 | scm/resourceFolder/context |
SCM 资源菜单 | scm/resourceState/context |
SCM 更改标题菜单 | scm/change/title |
SCM 源代码控制菜单 | scm/sourceControl |
视图标题菜单 | view/title |
查看项目菜单 | view/item/context |
macOS 触控栏 | touchBar |
注释线程标题菜单栏 | comments/commentThread/title |
注释线程上下文菜单 | comments/commentThread/context |
注释标题菜单栏 | comments/comment/title |
注释上下文菜单 | comments/comment/context |
时间线视图标题菜单栏 | timeline/title |
时间线视图项目上下文菜单 | timeline/item/context |
扩展视图上下文菜单 | extension/context |
- when 控制菜单什么时候出现,when 语句也不仅仅适用于菜单项的控制
when
属性常用方式:
when 不是字符串,它是 true 或 false 的布尔值,写成字符串形式 vscode 会去解析它,when可以直接传 true 或 false,例如 when: "true" 、when: "false"。
javascript
// 编辑器获得焦点时
"when": "editorFocus"
// 编辑器文本获得焦点
"when": "editorTextFocus"
// 编辑器获取焦点并且是js文件的时候
"when": "editorFocus && resourceLangId == javascript"
// 后缀不为.js
"when":"resourceExtname != .js"
// 只在Linux,Windows环境下生效
"when": "isLinux || isWindows"
-
alt定义备用命令,按住 alt 键打开菜单时将执行对应命令
没有按下alt键时,点击右键菜单执行的是 command 对应的命令,按下了 alt 键后执行的是 alt 对应的命令。
-
group 定义了菜单的分组
组间分组:控制菜单的分组和排序,不同的菜单拥有不同的默认分组。
编辑器上下文菜单 editor/context
中的默认组有:
- navigation :放在这个组的最前面
- 1_modification :更改组
- 9_cutcopypaste :编辑组
- z_commands :最后一个默认组,其中包含用于打开命令选项板的条目
navigation 是强制放在最前面的,其它分组都是按照0-9、a-z的顺序来排列的
资源管理器上下文菜单 explorer/context
的默认组有:
- navigation :放在这个组的最前面
- 2_workspace :与工作空间操作相关的命令
- 3_compare :与差异编辑器中的文件比较相关的命令
- 4_search :与在搜索视图中搜索相关的命令
- 5_cutcopypaste :与剪切,复制和粘贴文件相关的命令
- 7_modification :与修改文件相关的命令
editor/title
的默认组有:
- 1_diff : 与使用差异编辑器相关的命令
- 3_open : 与打开编辑器相关的命令
- 5_close : 与关闭编辑器相关的命令
组内分组:
默认同一个组的顺序取决于菜单名称,自定义排序可以再组后面通过 @数字 来自定义顺序。
javascript
"editor/context": [
{
"when": "editorFocus",
"command": "extension.sayHello",
// 强制放在navigation组的第2个
"group": "navigation@2"
},
{
"when": "editorFocus",
"command": "extension.demo.getCurrentFilePath",
// 强制放在navigation组的第1个
"group": "navigation@1"
}
]
keybindings
快捷键绑定,当快捷键被触发时,调用命令。
javascript
{
"contributes": {
"keybindings": [
{
"command": "extension.sayHello",
"key": "ctrl+f1",
"mac": "cmd+f1",
"when": "editorTextFocus"
}
]
}
}
views
视图,必须为视图指定标识符和名称。
当用户打开视图时,VScode 将会发出一个 activationEvent onView:${viewId}
javascript
{
"contributes": {
"views": {
"explorer": [
{
"id": "nodeDependencies",
"name": "Node Dependencies",
"when": "workspaceHasPackageJSON",
"icon": "media/dep.svg",
"contextualTitle": "Package Explorer"
}
]
}
}
}
视图 | 解释 |
---|---|
explorer | 活动栏中的资源管理器视图容器 |
scm | 活动栏中的源代码管理 (SCM) 视图容器 |
debug | 在活动栏中运行和调试视图容器 |
test | 活动栏中的测试视图容器 |
Custom view | 扩展提供的自定义视图容器 |
viewsContainers
视图容器,必须为视图容器指定 identifier (标识符)、title (标题)、和 icon。
javascript
{
"contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "package-explorer",
"title": "Package Explorer",
"icon": "resources/package-explorer.svg"
}
]
},
"views": {
"package-explorer": [
{
"id": "package-dependencies",
"name": "Dependencies"
},
{
"id": "package-outline",
"name": "Outline"
}
]
}
}
}
customEditors
告诉 VS Code 有关它提供的自定义编辑器的信息。customEditors 是一个数组,扩展可以有多个自定义编辑器。
javascript
"contributes": {
"customEditors": [
{
"viewType": "catEdit.catScratch",
"displayName": "Cat Scratch",
"selector": [
{
"filenamePattern": "*.cscratch"
}
],
"priority": "default"
}
]
}
属性 | 解释 |
---|---|
viewType | 自定义编辑器的唯一标识符 |
displayName | 在 VS Code 的 UI 中标识自定义编辑器的名称 |
selector | 指定自定义编辑器对哪些文件处于活动状态 |
priority | (可选)指定何时使用自定义编辑器(default/option) |
命令
vscode.commands.registerCommand 是注册命令的API,执行后会返回一个 Disposable 对象,所有注册类的 API 执行后都需要将返回结果放到 context.subscriptions 中。
javascript
context.subscriptions.push(vscode.commands.registerCommand('extension.sayHello', () => {
vscode.window.showInformationMessage('Hello World')
}));
回调参数函数
回调函数接收一个可选参数 uri:
- 资源管理器右键执行命令时,会把当前选中的资源路径 uri 作为参数传递
- 编辑器右键菜单执行时,会将当前打开文件路径 uri 作为参数传递
- Ctrl+Shift+P 执行命令时,参数为空
javascript
context.subscriptions.push(vscode.commands.registerCommand('extension.getCurrentFilePath', (uri) => {
vscode.window.showInformationMessage(`当前文件(夹)路径是:${uri ? uri.path : '空'}`)
}));
编辑器命令
vscode.commands.registerTextEditorCommand 命令是文本编辑器命令,与普通命令不同,它们仅在在编辑器被激活时调用才生效,此外,这个命令可以访问到当前活动编辑器 textEditor。
javascript
context.subscriptions.push(vscode.commands.registerTextEditorCommand('extension.testEditorCommand', (textEditor, edit) => {
console.log(textEditor, edit)
}));
执行命令
vscode api 中很多命令都是返回一个类似于 Promise 的 Thenable 对象,如果 api 里面返回的是这个对象,说明这个方法不是直接返回结果的。
javascript
vscode.commands.executeCommand('extension.returnResult', 'params1', 'params2', ...).then(result => {
console.log('命令结果', result);
});
获取所有命令
getCommands 可以用来获取所有命令,它接收一个参数表示是否过滤内部命令,默认为否。也可以直接打开快捷键设置,就可以看到所有的命令列表。
javascript
vscode.commands.getCommands().then(allCommands => {
console.log('所有命令:', allCommands);
});
复杂命令
vscode 内部有一些复杂命令,需要一些特殊参数并且通常有返回值、执行一些例如跳转到定义、执行代码高亮等操作、复杂命令列表可以参阅 vscode 插件开发官方文档。