繁体   English   中英

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

[英]Extending JavaScript syntax in Monaco Editor with full integration

我正在尝试扩展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中找到

我做了类似的事情。 我的解决方案是将非JS代码放在块注释中:

regularJsCode()
/* 
[your-syntax-identifying-start-token]
place any syntax you want here
[your-syntax-identifying-end-token]
*/
regularJsCode()

然后你可以使用你的工具,解析器,IDE扩展等来处理它。最酷的部分你可以使VSCode语法突出它,就像你想要的那样它看起来不像是一些黑客。

这种方法是可取的,因为您的JS文件仍然是100%有效的JS文件。

如果您仍然不想将语法放入注释中,那么您应该创建自己的文件扩展名,如.jsx / .tsx。 实际上,VSCode术语这意味着您需要使用语言服务器和东西创建VSCode扩展 这不是那么容易,但文档很好。 您可以使用语言服务器在VSCode扩展中组装自己的JS突出显示代码: https//github.com/sourcegraph/javascript-typescript-langserver

根据摩纳哥的创造者:

在架构上,您可以执行以下操作:

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

祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM