什么是 Monaco Editor
vscode 是我们经常在用的编辑器,它的前身是微软的一个叫 Monaco Workbench 的项目,而 Monaco Editor 就是从这个项目中成长出来的一个 web 编辑器,他们很大一部分的代码都是共用的,所以 Monaco Editor 和 VSCode 在编辑代码,交互及 UI 上几乎是一摸一样的。不同的是,两者的平台不一样, Monaco Editor 基于浏览器,而 VSCode 基于 electron ,所以功能上 VSCode 更加健全,性能比较强大。
安装
npm install monaco-editor --save
使用
<div id="monaco" class="monaco-editor"></div>
import * as monaco from 'monaco-editor';
this.fileEditor = this.monaco.editor.create(document.getElementById('monaco'), {
value: null,
language: 'sql' // 这里以sql为例
})
this.fileEditor.dispose(); // 使用完后销毁
这里引入 monaco 要注意,在 react 中以下面方式引入:
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
实现 ctrl+点击的函数或引用的文件转跳
monaco 的函数转跳功能需要手动把所有 编辑的代码加载到model上,才能搜索到转跳引索信息;
```// 创建model方法
monaco.editor.createModel(fileContent, lang, monaco.Uri.file("file://我的文件1.js"))
monaco.editor.createModel(fileContent, lang, monaco.Uri.file("file://我的文件2.js"))
然后需要重写鼠标点击后转跳的方法,我的实现方法是直接修改monaco的源码:
在源码找到 StandaloneCodeEditorServiceImpl 这个类
重新下面这个函数:
class StandaloneCodeEditorServiceImpl extends codeEditorServiceImpl_1.CodeEditorServiceImpl {
getActiveCodeEditor() {
return null; // not supported in the standalone case
}
openCodeEditor(input, source, sideBySide) {
if (!source) {
return Promise.resolve(null);
}
return Promise.resolve(this.doOpenEditor(source, input));
}
doOpenEditor(editor, input) {
const model = this.findModel(editor, input.resource);
const selection = (input.options ? input.options.selection : null);
if (!model) {
if (input.resource) {
const schema = input.resource.scheme;
if (schema === network_1.Schemas.http || schema === network_1.Schemas.https) {
// This is a fully qualified http or https URL
dom_1.windowOpenNoOpener(input.resource.toString());
return editor;
}
}
// 在此添加自定义打开文件、转跳函数
myFunc({uri:input.resource,selection});
return null;
}
if (selection) {
if (typeof selection.endLineNumber === 'number' && typeof selection.endColumn === 'number') {
editor.setSelection(selection);
editor.revealRangeInCenter(selection, 1 /* Immediate */);
}
else {
const pos = {
lineNumber: selection.startLineNumber,
column: selection.startColumn
};
editor.setPosition(pos);
editor.revealPositionInCenter(pos, 1 /* Immediate */);
}
}
// 在此添加自定义打开文件、转跳函数
myFunc({uri:input.resource,selection});
return editor;
}
听网友反馈后的修改方法
// 不修改源码,直接覆盖原方法,这样写也可以
editor._codeEditorService.doOpenEditor = function() {
console.log('触发鼠标+ctrl点击')
}