通过完全集成在Monaco Editor中扩展JavaScript语法

Ste*_*tis 5 javascript ide plugins typescript monaco-editor

我正在尝试扩展Monaco Editor以允许用户使用JavaScript和其他语言的混合编写,使用分隔符将它们分隔在同一文件中,类似于Markdown允许使用隔离代码块编写多种语言.

不同之处在于我希望保留Monaco为JavaScript构建的所有其他IDE功能,例如linting(通过诊断完成),智能自动完成,跳转到定义,自动格式化帮助程序以及所有其他IDE Monaco的内置JavaScript模式附带的功能.我希望这些功能仍在Monaco正在编辑的代码的JavaScript部分中工作,并且对于子语言部分禁用.

我的第一次尝试是调用setMonarchTokensProvider,传入TypeScript的tokenizer规则的修改版本.具体来说,我能够将起始栅栏定界符添加到根规则并为子语言创建新规则,就像使用@nextEmbedded一样,Monarch(Monaco的语法highligher)文档描述的方式.(出于测试目的,我一直在硬编码CSS作为嵌入式语言.)

当我为语言"javascript"调用这样的setMonarchTokensProvider时,它完全忽略了突出显示标记化器的语法,并将CSS的代码范围标记为无效的JavaScript,表明你不能以这种方式覆盖内置的JavaScript模式.

当我用一种新语言(例如"mylang")调用setMonarchTokensProvider并将编辑器设置为使用该语言时,它为这种CSS-in-JS混合语言提供了正确的语法高亮(!).但是,在JavaScript模式中找到的所有其他高级功能都不再存在.编辑器没有为同一文件中的类定义的方法进行任何智能自动完成,或者对于无效语法或其任何商标JavaScript IDE功能的任何编辑器内错误报告.

因此,我的下一次尝试是修改预先捆绑的Monaco代码的TypeScript定义,以包含我的自定义语法突出显示规则.这完全突出了我的CSS-in-JS代码(!),将语言设置为"typescript",保留所有其他功能完整(!),包括诊断报告(实时验证和错误下划线),自动完成, 所有的!(我没有尝试使用"javascript",但可以安全地假设它可能正常工作或者使其工作很简单,因为JavaScript实际上是作为Monaco中TypeScript模式的变体配置实现的.)

不幸的是,它还考虑了它的整个CSS部分,包括它周围的围栏,是无效的JavaScript代码.

事情几乎正常.

我知道这在理论上是可行的,因为在HTML模式下,您可以嵌入CSS或JS,完全支持正确的验证和自动完成以及所有其他IDE功能; 基本上,HTML文件中的每个子语言都在其自己的文件中工作:文件根目录中的HTML功能,样式标记中的CSS功能,脚本标记内的JS功能.

但是在Monaco内部深入研究TypeScript插件的实现,不清楚在哪里开始编辑它,无论是作为Monaco的用户,还是通过分叉并在必要时修补它.我开始尝试修改DiagnostcsAdapter [sic]并跟踪它实际实现的位置,但我陷入了两个函数调用深度,它似乎推动了语法验证承诺,返回一个稍后使用的值,但是实现了getSyntacticDiagnostics只是将工作外包给我在repo中找不到的其他实现,也没有在monaco-languages repovscode repo中找到.

Ste*_*tis 2

据摩纳哥的创造者所说:

从架构上来说,您可以执行以下操作:

  • 直接使用 monaco-editor-core
  • 为编辑器定义一种新语言
  • fork monaco-typescript 并将其更改为与您新定义的语言 ID 配合使用。然后,修改 TS 语言宿主代码,不将原始模型传递给 TypeScript,而是首先运行预处理,从文本中剥离您的自定义语言,然后仅将有效的 TypeScript 传递给 TS 编译器。一种想法是将删除的每个字符替换为空格。这将使所有位置/偏移计算工作无需您付出任何努力。

祝你好运!