Monaco Editor 使用入门
以前项目是用ace编辑器的,但是总有些不敬人意的地方。前端事件看见的VS Code编辑器Monaco Editor准备更换下,下面介绍一些使用中遇到的一点问题。代码提示
1.项目引用
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
项目中引用了editor.api.js,但是这个文件不包含一些默认的语言和插件,所以在使用的时候,还需要我们自己import
import 'monaco-editor/esm/vs/basic-languages/mysql/mysql.contribution';
import 'monaco-editor/esm/vs/editor/contrib/suggest/suggestController.js';
import 'monaco-editor/esm/vs/editor/contrib/bracketMatching/bracketMatching.js';
import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js';
如果嫌麻烦我们也可以使用editor.all.js
2.react组件封装
可以使用github项目,https://github.com/superRaytin/react-monaco-editor,也可以拿来项目里面改下,比较简单
其实在componentDidUpdate的方法中,使用这个方法this.editor.setValue,undo不能撤回上次的value,
如果项目中有别的需求可以使用
var model = this.editor.getModel();
model.pushEditOperations(
[],
[
{
range: model.getFullModelRange(),
text: prevProps.value
}
]
);
onDidChangeModelContent,方法产生的监听需要在组件销毁的时候dispose下
3.编辑器参数配置
查看以下代码文件 monaco-editor/esm/vs/editor/common/config/commonEditorConfig.js
minimap,scrollBeyondLastLine,Suggestion,snippet相关的
4.在光标处插入文本
跟ace使用差别比较大
var position = editor.getPosition();
editor.executeEdits('', [
{
range: {
startLineNumber: position.lineNumber,
startColumn: position.column,
endLineNumber: position.lineNumber,
endColumn: position.column
},
text: 'test'
}
]);
5.代码自动完成
下面代码是引用了monaco-editor自带的mysql的语法高亮里面的定义,设置的代码提示
import { language as mysqlLanguage } from 'monaco-editor/esm/vs/basic-languages/mysql/mysql.js';
monaco.languages.registerCompletionItemProvider('mysql', {
provideCompletionItems: function(model, position) {
// get editor content before the pointer
var textUntilPosition = model.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column
});
var match = textUntilPosition.match(/(\S+)$/);
if (!match) return [];
match = match[0].toUpperCase();
var suggestions = [];
mysqlLanguage.keywords.forEach(item => {
if (item.indexOf(match) !== -1) {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: item
});
}
});
mysqlLanguage.operators.forEach(item => {
if (item.indexOf(match) !== -1) {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Operator,
insertText: item
});
}
});
mysqlLanguage.builtinFunctions.forEach(item => {
if (item.indexOf(match) !== -1) {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Function,
insertText: item
});
}
});
return {
suggestions
};
}
});
如果你想增加代码片段,也可以直接添加下面的信息
{
label: 'ifelse',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: ['if (${1:condition}) {', '\t$0', '} else {', '\t', '}'].join('\n'),
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'If-Else Statement'
}
使用中发现,编辑器自带的默认的变量提示,在提供了自定义的registerCompletionItemProvider后会失效,暂时没找到什么好方法
默认的变量提示 monaco-editor/esm/vs/editor/common/services/editorWorkerServiceImpl.js
_this._register(modes.CompletionProviderRegistry.register('*', new WordBasedCompletionItemProvider(_this._workerManager, configurationService, _this._modelService)));
monaco-editor/esm/vs/editor/contrib/suggest/suggest.js
会根据注册的Provider的分组,语言默认的优先级不高,没有分到一组,找到了结果就不再会执行下面的组

6.语法高亮
官网的文档蛮详细的,和ace的差别不是很大,虽然我也没怎么看懂
https://microsoft.github.io/monaco-editor/monarch.html
可以在项目中找个相似的语言抄抄改改,结合着看官方文档
monaco-editor/esm/vs/basic-languages
高亮的样式需要在定义主题来对应,不是完全通过css处理的
monaco.editor.defineTheme('ace', {
base: 'vs',
inherit: true,
rules: [
{ token: '', foreground: '5c6773' },
{ token: 'invalid', foreground: 'ff3333' },
{ token: 'emphasis', fontStyle: 'italic' },
{ token: 'strong', fontStyle: 'bold' },
{ token: 'variable', foreground: '5c6773' },
{ token: 'variable.predefined', foreground: '5c6773' },
{ token: 'constant', foreground: 'f08c36' },
]
});
7.语法检测
语法检测,就需要编写对应的语法编译逻辑,这个不同语言不同的写法,一些也有现成的。这边主要介绍下怎么和编辑器交互,显示错误信息
错误信息hover显示需要插件 import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js';
//清楚mark
monaco.editor.setModelMarkers(model, 'eslint', []);
//添加mark
monaco.editor.setModelMarkers(model, 'eslint', [
{
startLineNumber: 2,
endLineNumber: 2,
startColumn: 2,
endColumn: 4,
message: 'Syntax error',
severity: 3,
source: 'ESLint',
code: 'asdasdas'
}
]);
对于上面的一些配置信息会对提示框有什么影响可以看下面的源码
monaco-editor/esm/vs/editor/common/services/modelServiceImpl.js ModelMarkerHandler._createDecorationOption
ModelMarkerHandler._createDecorationOption = function (marker) {
var className;
var color = undefined;
var zIndex;
var inlineClassName = undefined;
switch (marker.severity) {
case MarkerSeverity.Hint:
if (marker.tags && marker.tags.indexOf(1 /* Unnecessary */) >= 0) {
className = "squiggly-unnecessary" /* EditorUnnecessaryDecoration */;
}
else {
className = "squiggly-hint" /* EditorHintDecoration */;
}
zIndex = 0;
break;
case MarkerSeverity.Warning:
className = "squiggly-warning" /* EditorWarningDecoration */;
color = themeColorFromId(overviewRulerWarning);
zIndex = 20;
break;
case MarkerSeverity.Info:
className = "squiggly-info" /* EditorInfoDecoration */;
color = themeColorFromId(overviewRulerInfo);
zIndex = 10;
break;
case MarkerSeverity.Error:
default:
className = "squiggly-error" /* EditorErrorDecoration */;
color = themeColorFromId(overviewRulerError);
zIndex = 30;
break;
}
if (marker.tags) {
if (marker.tags.indexOf(1 /* Unnecessary */) !== -1) {
inlineClassName = "squiggly-inline-unnecessary" /* EditorUnnecessaryInlineDecoration */;
}
}
var hoverMessage = null;
var message = marker.message, source = marker.source, relatedInformation = marker.relatedInformation, code = marker.code;
if (typeof message === 'string') {
message = message.trim();
if (source) {
if (/\n/g.test(message)) {
if (code) {
message = nls.localize('diagAndSourceAndCodeMultiline', "[{0}]\n{1} [{2}]", source, message, code);
}
else {
message = nls.localize('diagAndSourceMultiline', "[{0}]\n{1}", source, message);
}
}
else {
if (code) {
message = nls.localize('diagAndSourceAndCode', "[{0}] {1} [{2}]", source, message, code);
}
else {
message = nls.localize('diagAndSource', "[{0}] {1}", source, message);
}
}
}
hoverMessage = new MarkdownString().appendCodeblock('_', message);
if (!isFalsyOrEmpty(relatedInformation)) {
hoverMessage.appendMarkdown('\n');
for (var _i = 0, _a = relatedInformation; _i < _a.length; _i++) {
var _b = _a[_i], message_1 = _b.message, resource = _b.resource, startLineNumber = _b.startLineNumber, startColumn = _b.startColumn;
hoverMessage.appendMarkdown("* [" + basename(resource.path) + "(" + startLineNumber + ", " + startColumn + ")](" + resource.toString(false) + "#" + startLineNumber + "," + startColumn + "): ");
hoverMessage.appendText("" + message_1);
hoverMessage.appendMarkdown('\n');
}
hoverMessage.appendMarkdown('\n');
}
}
Monaco Editor 使用入门的更多相关文章
- monaco editor + vue的配置
monaco editor是vscode的御用编辑器. 功能非常强大,使用方便轻巧,对js\ts等等语言支持都良好,能方便的扩展以支持其他语言或者自定义的特性. 夸了这么多,这里只说它一个问题: 这货 ...
- react & monaco editor & vs code
react & monaco editor & vs code monaco-editor https://microsoft.github.io/monaco-editor/inde ...
- monaco editor 实现自定义提示(sql为例)
monaco editor :https://www.cnblogs.com/XHappyness/p/9414177.html 这里实现自己定义的提示: .vue <template> ...
- Vue cli2.0 项目中使用Monaco Editor编辑器
monaco-editor 是微软出的一条开源web在线编辑器支持多种语言,代码高亮,代码提示等功能,与Visual Studio Code 功能几乎相同. 在项目中可能会用带代码编辑功能,或者展示代 ...
- 【软工】[技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE
[技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE 官方文档与重要参考资料 官方demo 官方API调用样例 Playground 官方API Doc,但其搜索框不支持模 ...
- js 在浏览器中使用 monaco editor
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 使用 TypeScript,React,ANTLR 和 Monaco Editor 创建一个自定义 Web 编辑器(二)
译文来源 欢迎阅读如何使用 TypeScript, React, ANTLR4, Monaco Editor 创建一个自定义 Web 编辑器系列的第二章节, 在这之前建议您阅读使用 TypeScrip ...
- Asp.Net Core 使用Monaco Editor 实现代码编辑器
在项目中经常有代码在线编辑的需求,比如修改基于Xml的配置文件,编辑Json格式的测试数据等.我们可以使用微软开源的在线代码编辑器Monaco Editor实现这些功能.Monaco Editor是著 ...
- 手把手教你实现在Monaco Editor中使用VSCode主题
背景 笔者开源了一个小项目code-run,类似codepen的一个工具,其中代码编辑器使用的是微软的Monaco Editor,这个库是直接从VSCode的源码中生成的,只不过是做了一点修改让它支持 ...
随机推荐
- Docker集群管理Swarm数据持久化
一.前言 和docker容器一样,Swarm集群中运行的服务也能够做数据持久化.我们可以通过volume.bind和nfs等方式来实现swarm集群应用数据的持久化.其实和docker数据持久化的形式 ...
- Java基础-日期格式化DateFormat类简介
Java基础-日期格式化DateFormat类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.DateFormat类概述 DateFormat 是日期/时间格式化子类的抽象 ...
- 笔记 jquery 的一个bug解决方法积累
本博客是自己在学习和工作途中的积累与总结,仅供自己参考,也欢迎大家转载,转载时请注明出处 当id或匹配条件中包含特殊字符时,浏览器控制台会报缺少")"的异常,解决办法目前有两个: ...
- Linux下U盘、SD卡挂载与卸载
1.手动挂载/卸载U盘.SD卡 对于ARM Linux来说,第一次使用U盘或SD时,U盘这个文件目录是不能直接进入的,我们需要对其进行挂载,然后再接下来的使用中就可以直接进行使用了.通过再网上查资料, ...
- Django 2.0.1 官方文档翻译: 快速安装向导 (Page5)
快速安装向导 (Page 5) 在你使用 Django 前,你需要先安装它.我们有一个完整的安装向导,它包含所有涉及的内容,这个向导会指导你进行一个简单的.最小化的安装,当你通过浏览介绍内容的时候,这 ...
- [转载]C语言程序的内存分配方式
"声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要 ...
- 推荐一些我所用的firefox 附加组件。
firefox之所以强大,很大程度上是因为它有着超多的扩展组件,来实现许多有趣的功能.这几天把我装的firefox附加组件整理下,个人认为是一般上网常用或者可以说是必备的组件,o(∩_∩)o ,晒晒. ...
- .net WebService 大数据量时性能的提高
1.直接返回DataSet对象 [WebMethod(Description = "直接返回DataSet对象")] public DataSet GetUserListDateS ...
- 超厉害的CSS3图片破碎爆炸效果!
var fx = { buffer : function(obj, cur, target, fnDo, fnEnd, fs){ if(!fs)fs=6; var now={}; var x=0; ...
- 微信小程序开发教程(六)配置——app.json、page.json详解
全局配置:app.json 微信小程序的全局配置保存在app.json文件中.开发者通过使用app.json来配置页面文件(pages)的路径.窗口(window)表现.设定网络超时时间值(netwo ...