乐趣区

关于visual-studio-code:monaco使用vscode相关语法高亮在浏览器上显示

阐明

  • 为了让 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.3

TOKENIZING 250971 lines using grammar source.js

Oniguruma: 550 ms., Onigasm: 381 ms. (1.4x faster)

Bootstrap CSS v3.1.1

TOKENIZING 127005 lines using grammar source.css

Oniguruma: 217 ms., Onigasm: 91 ms. (2.4x faster)

vscode.d.ts

TOKENIZING 264938 lines using grammar source.ts

Oniguruma: 356 ms., Onigasm: 191 ms. (1.9x faster)

JSON

TOKENIZING 103784 lines using grammar source.ts

Oniguruma: 312 ms., Onigasm: 185 ms. (1.7x faster)

Bootstrap CSS v3.1.1 minified

TOKENIZING 99967 lines using grammar source.css

Oniguruma: 231 ms., Onigasm: 167 ms. (1.4x faster)

jQuery v2.0.3 minified

TOKENIZING 83618 lines using grammar source.js

Oniguruma: 254 ms., Onigasm: 480 ms. (1.9x slower)

Bootstrap with multi-byte minified

TOKENIZING 116201 lines using grammar source.css

Oniguruma: 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);

 }

相干地址

  • 演示地址
  • 演示地址源码
  • 调用包源码
退出移动版