本文邀请cheeqi来回答,让他手把手教你如何开发一个爆款VS Code插件!
vscode 插件的形态和一个 npm 包非常相似,需要在项目的根目录添加 package.json,并且在其中增加一些 vscode 独家的设置。其中最主要的设置是 Activation Events(插件的激活时机) 和 contribution points (插件的能力)。接下来大家主要看看这两个配置具体是什么意思。
声明插件的激活时机 Activation Events偶将 vscode 的生命周期简单描述为下图。下面会做进一步解释。
[ vscode 插件生命周期(转载请注明作者 cheeqi) ]
activate() 函数 & deactivate() 函数
可以看到生命周期中最终要的两个节点就是activate函数和deactivate函数。这两个函数需要在插件 npm 模块的入口文件 export 出去给 vscode 主动调用。
其中,activate 会在 vscode 认为合适的时机调用,并且在插件的运行周期内只调用一次。因此在 activate 函数中开始启动插件的逻辑,是一个非常合适的时机。
deactivate 函数会在插件卸载之前调用,如果你的卸载逻辑中存在异步操作,那么只需要在deactivate 函数中 retuen 一个 promise 对象,vscode 会在 promise resolve 时才正式将插件卸载掉。
onXxxx Activation Events可以看到在activate函数之前,还有onLanguage等事件的描述,实际上这些就是声明在插件 package.json 文件中的 Activation Events。声明这些 Activation Events 后,vscode 就会在适当的时机回调插件中的 activate函数。vscode之所以这么设计,是为了节省资源开销,只在必要的时候才激活你的插件。当然,如果你的插件非常重要,不希望在某个事件之后才被激活,你可以声明Activation Events为*这样 vscode 就会在启动的时候就开始回调 activate函数。
插件的具体逻辑插件中的具体逻辑 vscode 没有做任何限制,你可以通过调用vscdoe提供的各种 api 对其进行扩充。不过需要注意的是,出于性能和移植性考虑,vscode不允许开发者直接操作dom。
关于vscode 的 api 可以参考
https://code.visualstudio.com/api/references/vscode-api 这是微软根据 vscode 的 d.ts 文件生成的文档
举个例子接下来大家来看几个插件的 Activation Events 声明
超越鼓励师 申明了 onCommand:ycy.showReminderView 和 * ,其实大家都知道只声明后一个就足够了
vuter 申明了 onLanguage:vue 所以他会在用户打开 vue 语言文件时被激活
vscode-icons 是一个纯主题插件,声明的是 *
GitLens 需要覆盖所有的文件,并且在vscode启动时就需要激活,他的声明是 *
关于 Activation Events 的说明可以参考官方文档 https://code.visualstudio.com/api/references/activation-events
声明插件的贡献点 contribution points
需要在 package.json 中声明的另一个重要字段就是 contribution points。 contribution points描述了当前插件支持哪些能力,以及对应能力的配置。
由于 vscode 禁止直接操作dom,往 UI 中插入功能的正确方式是声明贡献点。下图列出了 vscode 支持的所有贡献点。
[ 目前 vscode 支持的贡献点 ]
举个例子
接下来大家来看几个插件的 contribution points 声明
超越鼓励师 支持通过 commands 触发杨超越的提醒,同时可以配置提醒出现的时机,因此包括 commands / configuration
vuter 主要为 vue 文件提供语言支持,可以看到他提供的 contribution points 比较广,包括 commands / breakpoints / languages / grammars / configuration
vscode-icons 已支持主题为主,他提供了 iconThemes / commands / configuration
GitLens 是对vscode git 功能的增强,所以他的插入点集中在 UI 上的能力 configuration / commands / menus /resourceLabelFormatters / viewsContainers / views
关于 contribution points 的更多说明可以参考 https://code.visualstudio.com/api/references/contribution-points
编程语言支持那么,要怎么给 vscode 增加一门新的编程语言支持呢?
就像之前说的,vscode 主要支持两类编程语言支持: 声明类语言特性主要描述了代码高亮、代码片段等轻量级需要实时给出响应的语言特性支持;而程序类语言特性只要提供更加高级的跳到定义、查找引用、hover提示等对实时性要求不高,而且需要大量计算的语言能力。因此前者更加适合在 IDE 的主线程进行处理,而后者可以考虑拆分到其他线程甚至服务中进行计算。
声明类语言特性(基本支持)
下面主要以语法高亮为例子介绍声明式语言支持。
[ 从手写 paser 到 TextMate ]
在最初,微软的工程师们为web开发中常见的开发语言都手写了 paser。这类 paser 执行效率很高,但对开发者的能力要求也比较高,不太适合未来的插件扩展。从 vscode 1.8 版本开始,微软引入了 TextMate 的高亮语法,并逐步将原有的手写 paser 切换到这种语法上。
[ TextMate 官网 ]
TextMate 本身是 mac 下的一个文本编辑器,vscode 借用了他对语言高亮文本的定义方式。TextMate语法的本质是用一个 json 文件来描述语言中的 token 和结构,当然为了方便,也可以改用 YAML 并编译成json。
顺便一提,而 TextMate 语法使用的是 oniguruma 库来解析正则表达式,oniguruma 中支持一些 js 引擎目前还不支持的正则特性,因此在 vscode 中使用了一个 oniguruma 的 c++ 模块来加速正则表达式解析速度。
另外,为了方便开发者编写语法高亮插件,vscode还提供了一个 yomen 模板用于生成插件基本目录结构,以及一个名为 inspectTMScopes 的调试器查看词法分析的结果。
[ vscode 提供的 yomen 模板 ]
[ inspectTMScopes ]
除了语法高亮外,vscode还支持这些特性:注释切换、括号定义、自动闭合、Auto surrounding、代码折叠、word Pattern、缩进规则等,详见
https://code.visualstudio.com/api/language-extensions/language-configuration-guide