• 微软开源在线代码编辑器,编辑器天花板之Monaco Editor


    在这里插入图片描述

    各自随意
    彼此在意
    各自忙乱
    彼此牵挂
    ------致友情

    微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VSCode,而Monaco Editor(下文简称monaco)就是从这个项目中成长出来的一个web编辑器

    常见属性配置

          acceptSuggestionOnCommitCharacter: true, // 接受关于提交字符的建议
          acceptSuggestionOnEnter: 'on', // 接受输入建议 "on" | "off" | "smart" 
          accessibilityPageSize: 10, // 辅助功能页面大小 Number 说明:控制编辑器中可由屏幕阅读器读出的行数。警告:这对大于默认值的数字具有性能含义。
          accessibilitySupport: 'on', // 辅助功能支持 控制编辑器是否应在为屏幕阅读器优化的模式下运行。
          autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
          autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
          autoClosingOvertype: 'always', // 是否关闭改写 即使用insert模式时是覆盖后面的文字还是不覆盖后面的文字 "always" | "never" | "auto"
          autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
          autoIndent: 'None', 
    				参数如下:
    				None = 0,
            Keep = 1,
            Brackets = 2,
            Advanced = 3,
            Full = 4// 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
          automaticLayout: true, // 自动布局
          codeLens: false, // 是否显示codeLens 通过 CodeLens,你可以在专注于工作的同时了解代码所发生的情况 – 而无需离开编辑器。 可以查找代码引用、代码更改、关联的 Bug、工作项、代码评审和单元测试。
          codeLensFontFamily: '', // codeLens的字体样式
          codeLensFontSize: 14, // codeLens的字体大小
          colorDecorators: false, // 呈现内联色彩装饰器和颜色选择器
          comments: {
            ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
            insertSpace: true // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
          }, // 注释配置
          contextmenu: true, // 启用上下文菜单
          columnSelection: false, // 启用列编辑 按下shift键位然后按↑↓键位可以实现列选择 然后实现列编辑
          autoSurround: 'never', // 是否应自动环绕选择
          copyWithSyntaxHighlighting: true, // 是否应将语法突出显示复制到剪贴板中 即 当你复制到word中是否保持文字高亮颜色
          cursorBlinking: 'Solid', // 光标动画样式
          cursorSmoothCaretAnimation: true, // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
          cursorStyle: 'UnderlineThin', // "Block"|"BlockOutline"|"Line"|"LineThin"|"Underline"|"UnderlineThin" 光标样式
          cursorSurroundingLines: 0, // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
          cursorSurroundingLinesStyle: 'all', // "default" | "all" 光标环绕样式
          cursorWidth: 2, // <=25 光标宽度
          minimap: {
            enabled: false // 是否启用预览图
          }, // 预览图设置
          folding: true, // 是否启用代码折叠
          links: true, // 是否点击链接
          overviewRulerBorder: false, // 是否应围绕概览标尺绘制边框
          renderLineHighlight: 'gutter', // 当前行突出显示方式
          roundedSelection: false, // 选区是否有圆角
          scrollBeyondLastLine: false, // 设置编辑器是否可以滚动到最后一行之后
          readOnly: false, // 是否为只读模式
    			tabSize:2,//tab缩进长度
          theme: 'vs'// vs, hc-black, or vs-dark
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    一、自定义语言高亮

    1. 注册语言

    如果是自定义的语言需要先注册自定义语言名称

    monaco.languages.register({ id: 'configItem' });
    
    • 1

    2. 定义高亮

    规则 setMonarchTokensProvider 文档

    // 如果是已有语言高亮则不需要第一步直接设置高亮规则就可以
    monaco.languages.setMonarchTokensProvider('yaml', {
      tokenizer: {
        root: [[tokenRegx, { token: 'keyword' }]],
      },
    });
    // 自定义语言
    monaco.languages.setMonarchTokensProvider('configItem', {
      tokenizer: {
        root: [[tokenRegx, { token: 'keyword' }]],
      },
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    二、标记错误

    在编辑器中用波浪线标出错误提示
    通过 monaco.editor.setModelMarkers 方法标记位置点,文档

    const model = this.monacoEditor.getModel()      
    monaco.editor.setModelMarkers(model, 'json', [{ // json为语言类型
      startLineNumber: 2,
      endLineNumber: 2,
      startColumn: 1,
      endColumn: 10,
      severity: monaco.MarkerSeverity.Error,
      message: `语法错误`,
    }])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    获取语法错误列表

    monaco.editor.getModelMarkers({})
    
    • 1

    三、更新编辑器属性 options

    editorIns.updateOptions({
        readOnly: true,
    });
    
    • 1
    • 2
    • 3

    四、代码智能提示

    1. registerCompletionItemProvider

    代码智能提示

    useEffect(() => { 
    
      ThisEditor.current.registerCompletionItemProvider= monaco.languages.registerCompletionItemProvider('Python', {
        provideCompletionItems: function(model, position) {
          var word = model.getWordUntilPosition(position);
          console.log(ThisEditor.current.getModel().getValueLength(), 'model1')
          setLen(ThisEditor.current.getModel().getValueLength())
          console.log(word,'word')
          var range = {
            startLineNumber: position.lineNumber,
            endLineNumber: position.lineNumber,
            startColumn: word.startColumn,
            endColumn: word.endColumn
          };
          // let suggestions = [];
          // 这个keywords就是python.js文件中有的
    
          return {
            suggestions: createDependencyProposals(range)
          };
    
    
        }
      });
      return () => { 
        ThisEditor.current.registerCompletionItemProvider.dispose()//销毁
      }
    },[value])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    注意:monaco-editor代码提示registerCompletionItemProvider数据重复问题,provideCompletionItems方法多次执行,导致重复添加了相同的数据;completionItemProvider销毁

    五、销毁编辑器

    this.monacoEditor.dispose();
    
    • 1

    六、实时获取编辑器的值

    this.monacoEditor.onDidChangeModelContent(() => {
      this.monacoEditor.getValue() // 获取编辑器中的语句
    })
    
    • 1
    • 2
    • 3

    七、设置编辑器的值

    this.monacoEditor.setValue(newValue)
    
    • 1

    八、其他事件

    editor.getSelection();  //获取选中的行信息3
    
    editor.getModel().getLineContent(1);    //获取某一行的内容
    editor.getModel().getLinesContent();    //获取每一行的内容
    
    monaco.editor.setTheme('vs-dark');      //设置主题
    
    editor._configuration._rawOptions.language  //获取编辑器当前语言(初始化值)
    editor.getModel().getLanguageId()           //动态(已改变编辑器语言)
    
    //内容改变事件
    editor.onDidChangeModelContent(function(e){
      console.log(e);
      console.log(editor.getValue());
    });
    
    //添加按键监听
    editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, function () {
      console.log('Ctrl + S 保存')
    })
    
    editor.trigger('a', 'editor.action.formatDocument') //触发:格式化文档,更多支持项:editor._actions
    
    //渲染代码得到HTML
    monaco.editor.colorize('console.log("Hello world!");', 'javascript').then(function (data) {
        console.log(data);
    });
    
    //渲染节点代码
    
    console.log("Hello world!");
    monaco.editor.colorizeElement(document.getElementById('code'));
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    1. 创建model与editor

    在Monaco Editor中,每个用户可见的编辑器均对应一个IStandaloneCodeEditor。在构造时可以指定一系列选项,如行号、minimap等。
    其中,每个编辑器的代码内容等信息存储在ITextModel中。model保存了文档内容、文档语言、文档路径等一系列信息,当editor关闭后model仍保留在内存中
    IEditor: 光标位置、销毁editor等

    2. 获取代码、代码长度、光标位置等信息

    获取与editor或model的相关信息是简单的,在ITextModelIStandaloneCodeEditor的API文档中不难找到。
    以下是一些常用信息,包括获取model实例、获取代码内容(字符串)、获取代码长度、获取光标位置、跳光标到给定位置、置焦点到某编辑器等。

    export function getModel(editor) {
    	return editor.getModel();
    }
    
    export function getCode(editor) {
    	return editor.getModel().getValue();
    }
    
    export function getCodeLength(editor) {
    	// chars, including \n, \t !!!
    	return editor.getModel().getValueLength();
    }
    
    export function getCursorPosition(editor) {
    	let line = editor.getPosition().lineNumber;
    	let column = editor.getPosition().column;
    	return { ln: line, col: column };
    }
    
    export function setCursorPosition(editor, ln, col) {
    	let pos = { lineNumber: ln, column: col };
    	editor.setPosition(pos);
    }
    
    export function setFocus(editor) {
        editor.focus();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3. getSelection()

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

    {
        startLineNumber: 0,
        startColumnNumber: 0,
        endLineNumber: 0,
        endColumnNumber: 0,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4. Diff Editor

    1. 通过 monaco.editor.createDiffEditor 方法创建 diff editor 实例;
    2. 通过 diffEditorIns.setModel 方法设置 diff 的原始值和现在的值
    diffEditorIns.setModel({
      original: monaco.editor.createModel(originalValue, 'javascript'),
      modified: monaco.editor.createModel(nowValue, 'javascript'),
    });
    
    • 1
    • 2
    • 3
    • 4

    5. onDidChangeCursorSelection

    监听光标是否发生了修改

  • 相关阅读:
    ABB GFD563A101 3BHE046836R0101ABB GFD563A101 3BHE046836R0101
    详解Spring的循环依赖
    Vulnhub靶机网卡启动失败(Raise network interfaces)
    从一键部署热门游戏幻兽帕鲁到探索未来个人元宇宙
    deepin V23通过flathub安装steam畅玩游戏
    【云原生进阶之PaaS中间件】第一章Redis-2.4缓存更新机制
    【HCIA】动态路由协议分类、OSPF
    全球名校AI课程库(38)| 马萨诸塞大学 · 自然语言处理进阶课程『Advanced Natural Language Processing』
    python爬虫-异步爬虫
    瑞吉外卖07-对于分类信息的CRUD
  • 原文地址:https://blog.csdn.net/qq_37440870/article/details/126563662