monaco-editor使⽤总结
monaco-editor 介绍
微软之前有个项⽬叫做 Monaco Workbench,后来这个项⽬变成了VSCode,⽽ Monaco Editor 就是从这个项⽬中成长出来的⼀个web编辑器,他们很⼤⼀部分的代码(monaco-editor-core)都是共⽤的,所以monaco和VSCode在编辑代码,交互以及UI上⼏乎是⼀摸⼀样的,有点不同的是,两者的平台不⼀样,monaco基于浏览器,⽽VSCode基于electron,所以功能上VSCode更加健全,并且性能⽐较强⼤。
简单来讲,monaco-editor 是⼀个浏览器版本的 vscode。⽬前很多浏览器上的 "云编辑器" 都是基于 monaco-editor 来做的。
安装引⼊
安装
tnpm install monaco-editor
页⾯注册使⽤
import * as monaco from 'monaco-editor';
import React, { useRef, useEffect } from 'react';
const CodeEditor: React.FC = () => {
const editorRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (editorRef.current) {
const editorIns = ate(editorRef.current, {
language: 'sql',
value,
folding: true,
theme: 'vs',
scrollbar: {
verticalScrollbarSize: 8,
horizontalScrollbarSize: 8,
},
minimap: {
enabled: withMiniMap,
},
多文本编辑器editor什么意思formatOnPaste: true,
renderValidationDecorations: 'on',
});
}
}, [editorRef]);
return <div ref={editorRef}></div>;
};
monaco-editor-webpack-plugin
在 monaco-editor 中需要处理 ts、html、json等语⾔时需要单独的引⼊相应的 worker 。当我们使⽤ webpack 来作为构建⼯具的时候会不是很⽅便,这个时候可以通过 monaco-editor-webpack-plugin 来帮助我们处理这些问题,它可以⽤来做:
1. ⾃动注⼊getWorkerUrl全局变量;
2. 处理worker的编译配置;
3. ⾃动引⼊控件和语⾔包。
相关功能
编辑器适配屏幕缩放
1. ⼿动调⽤ editorIns.layout() ⽅法
2. 实例化编辑器的时候 automaticLayout 声明为 true (可能有性能问题)
Diff Editor
1. 通过 ateDiffEditor ⽅法创建 diff editor 实例;
2. 通过 diffEditorIns.setModel ⽅法设置 diff 的原始值和现在的值
diffEditorIns.setModel({
original: ateModel(originalValue, 'javascript'),
modified: ateModel(nowValue, 'javascript'),
});
更新编辑器 options
通过 updateOptions 来更新,⽐如
editorIns.updateOptions({
readOnly: true,
});
⾃定义语⾔⾼亮
1. 如果是⾃定义的语⾔需要先注册⾃定义语⾔名称
ister({ id: 'configItem' });
1. 定义⾼亮规则
// 如果是已有语⾔⾼亮则不需要第⼀步直接设置⾼亮规则就可以
monaco.languages.setMonarchTokensProvider('yaml', {
tokenizer: {
root: [[tokenRegx, { token: 'keyword' }]],
},
});
// ⾃定义语⾔
monaco.languages.setMonarchTokensProvider('configItem', {
tokenizer: {
root: [[tokenRegx, { token: 'keyword' }]],
},
});
标记错误
通过 monaco.editor.setModelMarkers ⽅法标记位置点,
monaco.editor.setModelMarkers(
model,
'javascript',
[{
startLineNumber: 2,
endLineNumber: 2,
startColumn: 1,
endColumn: 10,
severity: monaco.MarkerSeverity.Error,
message: `语法错误`,
}],
);
Quick Fix
通过 setModelMarkers 标记错误或者警告之后 hover 会有⼀个 modal ⾥⾯展⽰错误信息以及 quick fix 的选项,如何来定义 quick fix 的⾏为呢。这⾥需要通过 isterCodeActionProvider 来定义quick fix 的⾏为,⽀持 edit 和 command 两种类型的⾏为。
1. edit 是直接替换被指定的位置的⽂本;
2. command 则是完全的⾃定义 fix ⾏为,可以做任何事情。
CompleteProvider
⽤于定义⾃动完成的 provider
HoverProvider
⽤于定义⿏标 hover 的 provider。
public provideHover(
model: monaco.editor.ITextModel,
position: monaco.Position,
token: monaco.CancellationToken,
)
PS: 貌似不⽀持关键词定义 hover tips 解决⽅案:
1. 获取 hover 位置;
2. 获取 hover 的那⼀⾏内容 LineContent(lineNumber) ;
3. 匹配 hover ⾏关键字;
4. 获取关键字位置;
5. 根据⿏标 hover column 确定 hover 的关键字位置;
6. 提⽰关键字内容等。
本地化 i18n
⽬前 monaco-editor 官⽅仅⽀持 AMD ⽅式的 i18n 配置。补丁⽅案
Dispose
monaco-editor 中提供了许多的回调以及 provider 供我们使⽤,⼀些场景下我们需要 removeEventListener ,这个时候我们可以使⽤ dispose 来实现。⼤部分情况下各种回调或 provider 都是返回⼀个包含 dispose 函数的对象,只要执⾏下这个函数就可以解除功能。
let disposeable: monaco.IDisposable;
// 取消 hover provider
disposeable?.dispose();
disposeable = isterHoverProvider(language, new ConfigItemHoverProvider(configItemList));
参考
1.
2.
3.