VS Code插件开发概览

theme以及编程语言相关的插件不在本文讨论之列

开发环境

基于Yeoman和generator-code

npm install -g yo generator-code
yo code

以上会生成一个vscode插件hello wrold项目
在vscode中打开后用按F5可进入调试模式

重要文件:

  • extension.js 主文件,插件的逻辑位于此文件中
  • package.json 插件的重要配置位于此文件中

插件的使用场景

注意 插件无法修改vscode的dom

  • 运行命令,这是vscode插件最主要的功能,命令需要通过vscode提供的api注册以后使用
  • 提供插件的自定义配置项
  • 按键绑定
  • 定义菜单,vscode中不同的区域有不同的菜单配置项目,例如编辑器区和侧边栏区
  • 数据存储,共有4种存储空间
    • ExtensionContext.workspaceState 存储键值对形式的小数据,仅对同一workspace可见
    • ExtensionContext.globalState 存储键值对形式的小数据,全部workspace可见
    • ExtensionContext.storagePath 存储数据在本机文件中,用于数据量较大的场景 仅同一workspace可见
    • ExtensionContext.globalStoragePath 存储数据在本机文件中,用于数据量较大的场景 全部workspace可见
  • 显示通知,共有三种形式
    • window.showInformationMessage 信息通知框
    • window.showWarningMessage 警告通知框
    • window.showErrorMessage 错误通知框
  • 快速输入 支持选择和输入两种形式
  • 文件选择器
  • 主题设置
  • 编程语言特性支持 代码高亮 snippets,lint等
  • 自定义工作区界面 侧边栏 状态栏等
  • 调试
  • 新建webview

配置项

插件的配置位于package.json中,下面列出比较重要的配置项

  • name 插件名
  • publisher 发布人
  • main 入口文件
  • activationEvents 配置插件何时被激活
  • contributes 插件主要的配置项
    • configuration 插件的可配置选项 比如提供用户名和密码的配置项
    • commands 指定插件可运行的命令 指定的命令可在vscode的命令面板中使用,也可以配置在menu选项中,在右键菜单项或者其他菜单中运行
    • menus 为command指定菜单配置 例如编辑器右键菜单,mac的touchbar菜单,侧边栏菜单
    • themes 配置一个主题 主题文件路径通过path来指定
  • displayName 插件在市场所显示的名字

插件的激活时机

插件配置项中的activationEvents字段指定了在何时插件会被触发,同时,插件的主文件必须要export一个activate函数,当activationEvents中指定的任意事件触发时,就会执行activate函数,注意,仅执行一次。 可监听的事件如下:

  • onCommand 监听某个命令执行时激活插件
  • onLanguage 监听某种语言 比如要开发一个vue的代码高亮的插件,那么指定onLanguage:vue 当检测到是vue语言的时候激活插件
  • onDebug 进行debug时触发插件
  • workspaceContains 当某个文件夹被打开,并且文件夹中包含指定的文件的时候触发,例如"workspaceContains:**/.editorconfig"
  • onFileSystem 当从某个特定的文件系统上读取文件时激活"onFileSystem:sftp"
  • onView 某个特定的view被打开时激活
  • onUri vscode或者vscode-insiders类型的uri资源被打开时触发
  • onWebviewPanel 当恢复某个webview时激活,webview需要调用vscode的api手动创建,所以必须需要先创建一个特定的webview后才能使用该事件
  • * 代表在vscode启动时激活,尽量少用

Command

command是vscode插件运作的主要单元。 vscode本身内置大量的command,也开放了api让用户自定义command。

主要的command管理api如下:

  • vscode.commands.executeCommand 执行一个command
  • vscode.commands.registerCommand 注册一个自定义command

自定义command

上文中有提到package.json中有好几个字段都涉及到了command
实际上commnad真正的注册发生在调用registerCommand命令

调用commnad的场景有:

  • 选择菜单项或者其他面板按钮
  • 命令行面板
  • 快捷键
  • 程序中调用

package.json中不同字段下的字段是为了应对不同场景下的command调用

extension.js
const vscode = require('vscode');
function activate(context) {
    let disposable =  vscode.commands.registerCommand('myExtension.sayHello', function () {
    
    })
    context.subscriptions.push(disposable);
}
exports.activate = activate;
contributes.commands

将command暴露给命令行面板,如下配置以后使用户可在命令行面板中调用

{
  "contributes": {
    "commands": [
      {
        "command": "myExtension.sayHello",
        "title": "Say Hello"
      }
    ]
  }
}
activationEvents

在command调用时,激活插件,否则command不会生效,对于自定义command,这是必须的配置

{
  "activationEvents": ["onCommand:myExtension.sayHello"]
}
contributes.menus

将command暴露给菜单项,在菜单项点击时触发command

{
  "contributes": {
    "menus": {
      "editor/context": [
        {
            "when": "editorFocus",
            "command": "myExtension.sayHello"
        }
      ]
    }
  }
}

按如上所示,三个地方都配置后,在编辑器右键菜单中将会出现Say Hello,点击后将会调用extension.js中定义的myExtension.sayHello函数,同时在命令行面板中也会出现Say Hello命令

插件的自定义配置

如下图所示,插件如果需要暴露自定义配置,此功能需要在package.json的contributes 中配置 -w1007

"contributes": {
    "configuration": {
        "title": "TypeScript",
        "properties": {
            "typescript.useCodeSnippetsOnMethodSuggest": {
                "type": "boolean",
                "default": false,
                "description": "Complete functions with their parameter signature."
            },
            "typescript.tsdk": {
                "type": ["string", "null"],
                "default": null,
                "description": "Specifies the folder path containing the tsserver and lib*.d.ts files to use."
            }
        }
    }
}

然后可通过内置apivscode.workspace.getConfiguration().get(xxx)拿到用户所设置的值

发布插件

两种比较好的方式

  • 通过vsce工具打包成vsix文件,其他用户通过vscode提供的vsix安装方式即可安装使用
  • 发布到应用市场

两种方式都需要在h ttps://dev.azure.com/vscode 注册账号,然后生成token 注意生成token时将scope选为full access,官网给的例子是custom,实际使用时会报错。 然后npm安装vsce,进行如下几步

  • vsce create-publisher 这个过程需输入上一步创建的token
  • vsce login
  • vsce publish(发布到应用市场) 或 vsce package (打包成vsix) 这个过程类似npm发布包

为了减小插件体积,尽量使用webpack打包插件后发布,如果直接发布,插件内会包含大量冗余文件。具体引入方式可参见官网 https://code.visualstudio.com/api/working-with-extensions/bundling-extension

注意

webpack配置中的output.path选项指定了插件打包后的输出目录,package.json中的main字段指定插件的入口文件,需要注意的是开发模式下和打包后,入口文件并不是同一个,在开发模式下main可能指向./extension.js,打包后需指向./dist/extension.js

个人开发的两个插件 http://idinr.com/artifact/autoclass/