作者:enoyao,腾讯工程师
在前几天腾讯文档 AlloyTeam 给 VSCode 合入了大概 400 行核心代码,主要涉及到 VSCode 配置化的部分,增强其插件化能力,提供更多的匹配接口,整理部分代码结构和补充功能单测。
![](https://i-blog.csdnimg.cn/blog_migrate/5cdad5042c2dd350502f03dedb9212ab.png)
由于腾讯文档最近在完善我们的配置化系统,在完善的过程也探索了多种实现方案,也分析了很多产品的实现方式,如大名鼎鼎的 VSCode,我们也希望把我们积累经验贡献给开源社区,一起共同进步。
![](https://i-blog.csdnimg.cn/blog_migrate/3e7a5a689dfce9c1d55b3fc026551157.png)
其中代码的提交者为 AlloyTeam 的工程师 @Wscats ,而合入代码的是微软 VSCode 团队现主要负责人之一 Alexdima,也是 Monaco Editor 负责人(VSCode 前身),也是同 Erich Gamma (VSCode 之父) 来自苏黎世同一个团队,特别感谢他和他团队的支持,还帮我们挖坑的代码写了不少单测...
![](https://i-blog.csdnimg.cn/blog_migrate/fe3cba3d9392c0acd17baa38c42c854d.png)
由于我们是给 VSCode 贡献了这部分代码,那我们就从 VSCode 本身开始聊起,我们给 VSCode 的配置化贡献了什么?我相信大部分的开发者都使用过 VSCode,所以配置化应该不陌生,由于使用者众多,任何编辑器其实都不能做到面面俱到去满足所有的使用者,如果什么用户的需求都要满足,就需要把所有的功能都塞进去,这不但臃肿,还不好维护。
所以我们需要配置化去丰富和拓展,减轻编辑器本身的包袱,把部分内容移交给用户/合作方去定制,就如我们可以在 VSCode 的设置面板选择编辑器的颜色,更换它的主题背景。
![](https://i-blog.csdnimg.cn/blog_migrate/ab92d822e08dcb94e8c5e6b07f1aabd0.png)
也可以在快捷键面板里面绑定或者解绑我们的快捷键,更换我们的字体大小和改变我们的悬浮信息等,这些其实都离不开背后实现的一套配置化系统。
![](https://i-blog.csdnimg.cn/blog_migrate/065f88c074e057357da95d131a622721.png)
上面举例的都是有默认的配置,可以通过面板去更改的,当然还有些隐藏的配置我们无需在面板改变也能实现配置,比如缩小 VSCode 的界面大小,某些功能就会自动隐藏,这种也是属于配置化。
![](https://i-blog.csdnimg.cn/blog_migrate/7f31c41d691d7690a2ace618f172d179.png)
我们除了通过面板可视化操作,还可以通过插件来配置界面,VSCode 中插件的核心就是一个配置文件 package.json
,里面拥有提供了配置点,只需按要求编写正确的配置点就可以改变 VSCode 的视图状态,里面最主要的字段就是 contributes
字段:
contributes.configuration:插件有哪些可供用户配置的选项,提供的界面跟上面切背景颜色棉棒相似
contributes.configurationDefaults:覆盖 vscode 默认的一些编辑器配置
contributes.commands:向 vscode 的命令系统注册一些可供用户调用的命令
contributes.menus:扩展菜单
...
这是更换编辑器各个位置颜色的配置参数,很简单明了。
{
"colors": {
"activityBar.background": "#333842",
"activityBar.foreground": "#D7DAE0",
"activityBarBadge.background": "#528BFF"
}
}
里面的代码思路其实就是挖了一个洞
给第三方,然后支持参数的填入,下面代码就是一个示例,把配置文件的颜色读取出来,然后生成一个新的颜色规则,达到控制面板背景颜色的功能。
const color = theme.getColor(registerColor('activityBar.background'));
if (color) {
collector.addRule(
`.monaco-workbench .activitybar > .content > .home-bar > .home-bar-icon-badge { background-color: ${color}}`
);
}
上面这个最基本的能力在代码实现里面应该是毫无难度的,只需要挖空一个配置点即可,但是实际肯定会再复杂点,此时如果用户想在此功能基础上继续做配置,比如编辑器在 Win 系统的时候颜色变深,在 Mac 系统的时候颜色变浅.
if (color) {
if (isMacintosh) {
color = darken(color);
}
if (isWindows) {
color = lighter(color);
}
collector.addRule(
`.monaco-workbench .activitybar > .content > .home-bar > .home-bar-icon-badge { background-color: ${color}}`
);
}
这里的就需要知会开发者,讲道理对开发者来说难度也不是很大,无非就是往代码里面在插入几段条件判断的代码而已嘛,但是某一天用户说我又得改了,我想在分辨率大于 855 的时候颜色变深,在分辨率小于等于 855 的时候颜色变浅,并且遇到 Linux 系统也得颜色变深。那此时再变更代码来满足客户的需求,不得继续加代码如下了:
if (color) {
if (isMacintosh || window.innerWidth > 855) {
color = darken(color);
}
if (isLinux) {
color = darken(color);
}
if (isWindows || window.innerWidth <= 855) {
color = lighter(color);
}
collector.addRule(
`.monaco-workbench .activitybar > .content > .home-bar > .home-bar-icon-badge { background-color: ${color}}`
);
}
那开发宝宝那能遭得住,谁知道那天的又得改呢,要知道编辑器用户可是上千万啊,用户的需求可是花里胡哨,怎么接得住。
![](https://i-blog.csdnimg.cn/blog_migrate/b33a110a3310f726c3320372c87b948e.png)
那开发的自己去定制规范,不能让你随意来,我提供变暗和变深的接口,但是规则我不再负责写了,请用户自己提供,所以开发可能会继续调整下代码:
class Color {
color