阐明

  • 为了让monaco应用vscode的主题

尝试实现(弯路)

主题的间接转换

  • 刚开始本认为是两者主题的格局不同,尝试转换后发现还是不能失常应用
  • 后果发现两者的token基本不同,也就是宰割代码每一部分的命名不同

monarch转换textmate

  • 发现monaco应用的是本人设计的monarch来实现语法高亮,然而vscode应用的是textmate的格局
textmate是苹果的那种
  • 于是想到如果实现一种转换逻辑,将textmate->monarch,那么monaco就能够应用vscode的主题了(因为token一样了)
  • 当学完单方的逻辑后,钻研了posix与pcre正则的转换,进行事件时,发现一个致命问题..monach无奈实现后行断言((?<=})),这就导致了一般的转换根本无法实现.(简单的...可能有生之年系列吧)

最终解决方案

  • 应用vscode-textmate代替原monarch
  • 其实这个在开始钻研的时候就有了,然而网上说因为不能间接调用c,所以应用wasm的效率比桌面端低,所以并没有无限思考(有点自卑了...)
  • 最终性能这块,看到了vscode-textmatebenchmark,测试了一波.发现除了js的解析比桌面端慢两倍,其余的甚至比桌面端快...有点费解了(不晓得本人有没有钻研错,如果有说的不对请拍砖)
jQuery v2.0.3TOKENIZING 250971 lines using grammar source.jsOniguruma: 550 ms., Onigasm: 381 ms. (1.4x faster)Bootstrap CSS v3.1.1TOKENIZING 127005 lines using grammar source.cssOniguruma: 217 ms., Onigasm: 91 ms. (2.4x faster)vscode.d.tsTOKENIZING 264938 lines using grammar source.tsOniguruma: 356 ms., Onigasm: 191 ms. (1.9x faster)JSONTOKENIZING 103784 lines using grammar source.tsOniguruma: 312 ms., Onigasm: 185 ms. (1.7x faster)Bootstrap CSS v3.1.1 minifiedTOKENIZING 99967 lines using grammar source.cssOniguruma: 231 ms., Onigasm: 167 ms. (1.4x faster)jQuery v2.0.3 minifiedTOKENIZING 83618 lines using grammar source.jsOniguruma: 254 ms., Onigasm: 480 ms. (1.9x slower)Bootstrap with multi-byte minifiedTOKENIZING 116201 lines using grammar source.cssOniguruma: 248 ms., Onigasm: 196 ms. (1.3x faster)

实现原理

  • 这个计划是从monaco-tm中得来的,然而最终欠缺了主题应用,能够从vscode中无缝移植主题,欠缺了语言插件,能够从vscode无缝迁徙tmLanguage的插件,并且反对语言点注入
  • grammar是用来解析语法的,会在调用这个语言的时候,加载对应的语法文件
具体须要实现monaco.languages.EncodedTokensProvider接口传给setTokensProvider做参数

setTokensProvider代替了setMonarchTokensProvider

  • configuration是用来配置一些折叠,括号,正文等货色...和原来的monaco一样
  • theme就是用来申请加载主题的
因为语法的解析变成了vscode-textmate,所以不能应用传统的形式来加载主题,须要从Registry中拿到ColorMap而后定义给主题
  • 最初通过监听应用语言时加载对应的语法解析文件

应用

  • ng下曾经封装好了依赖包的应用,非ng框架也能够稍作批改应用
  • 包地址cyia-ngx-common
  • 引入模块CyiaMonacoTextmateModule,组件中通过依赖注入拿到CyiaMonacoTextmateService服务
 this.service.setMonaco(monaco); this.service.init().then(async () => { const themeList = await this.service.getThemeList(); this.themeList = themeList; this.selectedTheme = themeList[1]; const name = await this.service.defineTheme(this.selectedTheme); this.instance = monaco.editor.create( this.containerElement?.nativeElement, { theme: name, value: `let a=6;`, language: this.selectedLanguage, minimap: { enabled: false, }, automaticLayout: true, } ); }); //切换主题 async change(e) { const name = await this.service.defineTheme(e); monaco.editor.setTheme(name); }

相干地址

  • 演示地址
  • 演示地址源码
  • 调用包源码