Monaco Editor 使用指南

32,614 阅读2分钟

为什么要写这篇文章?

最近开发了一个简单的在线代码编辑器,基于 Monaco Editor 实现,没有了解过 Monaco 的人可能不知道,我们常用的 VS Code 也是基于它实现的~

回到正题,Monaco Editor 有一份完整的官方文档,那为什么还要写这个文章?因为官方文档是在是太难用了,api 难找不说,找到了也是看得云里雾里,可能是我查阅的姿势不对吧,欢迎有文档使用经验的朋友在评论中指教~

话不多说,下面开始总结我在开发中的常用功能。

开始使用

我使用的是 Vue 版本的包 monaco-editor-vue,使用方式如下:

<template>
  <div id="app">
    <MonacoEditor
      theme="vs-dark"
      language="javascript"
      :editorMounted="onEditorMounted"
      :options="options"
      @change="onChange"
    ></MonacoEditor>
  </div>
</template>
 
<script>
import MonacoEditor from 'monaco-editor-vue';
export default {
  name: "App",
  components: {
    MonacoEditor
  },
  data() {
    return {
      options: {
        value: '', // 初始值
        foldingStrategy: 'indentation', // 代码可分小段折叠
        automaticLayout: true, // 自适应布局
        overviewRulerBorder: false, // 不要滚动条的边框
        autoClosingBrackets: true,
        tabSize: 2, // tab 缩进长度
        minimap: {
          enabled: false, // 不要小地图
        },
      },
    }
  },
  methods: {
    onChange(value) {
      console.log(value);
    }

    onEditorMounted(editor, monaco) {
      window.editor = editor
      window.monaco = monaco
    },
  }
};
</script>

常用 api

editor.getValue()

获取编辑器中的所有文本,并生成一个字符串返回,会保留所有信息(换行、缩进、注释等等)。

editor.getSelection()

获取编辑器中被选中文案的 range ,返回一个对象,如下:

{
    startLineNumber: 0,
    startColumnNumber: 0,
    endLineNumber: 0,
    endColumnNumber: 0,
}

editor.getModel()

获取编辑器当前的 textmodel,一般不会直接使用,通过 textmodel 可以对文本各种操作。

editor.getModel().findMatches(str|regexp)

功能和 “⌘ + F” 一致,通过字符串或正则表达式查找编辑器内匹配的文本,并返回匹配文本 range 的集合。

editor.getModel().getValueInRange(range)

通过 range 获取范围内的文本,返回一个字符串。

editor.getModel().getLinesContent(lineNumber)

如果传入 lineNumber,则返回对应行的文本字符串,不传参则返回所有行的文本字符串的集合。

editor.executeEdits()

在指定位置插入代码,跟 editor.setValue() 不同的地方是,可以用 “⌘ + Z” 撤销输入。

editor.executeEdits('insert-code', [
  {
    range: {
      startLineNumber,
      startColumn,
      endLineNumber,
      endColumn,
    },
    text,
  },
])

editor.addAction()

在右键菜单里增加一栏自定义的操作。

this.editor.addAction({
  id: '', // 菜单项 id
  label: '', // 菜单项名称
  keybindings: [this.monaco.KeyMod.CtrlCmd | this.monaco.KeyCode.KEY_J], // 绑定快捷键
  contextMenuGroupId: '9_cutcopypaste', // 所属菜单的分组
  run: () => {}, // 点击后执行的操作
})

monaco.editor.setModelMarkers()

在编辑器中用波浪线标出错误提示。

monaco.editor.setModelMarkers(editor.getModel(), 'owner', [
  {
    startLineNumber,
    startColumn,
    endLineNumber,
    endColumn,
    message, // 提示文案
    severity: monaco.MarkerSeverity.Error, // 提示的类型
  },
])