0


【超详细】 对 AceEditor 二次封装 及 自定义扩展语言实现

📢 前言

最近调研前端代码编辑器,选中了 Ace editor,其本身功能丰富,扩展性也极强,插件目前更新稳定。ace 本身支持上百种语言的语法,然鹅日常项目中总有些奇葩的需求,以致我们需要去了解更多的技术研究。
技术支持: Vue3 + Vite ,基于 ace-builds 进行二次扩展封装。

📄 Ace 简介

1、什么是 Ace editor ?

Ace(Ajax.org Cloud9 Editor)是一个用 JavaScript 编写的可嵌入代码编辑器。它与 Sublime,Vim 和 TextMate 等本地编辑器的功能和性能相匹配。它可以轻松地嵌入任何网页和 JavaScript 应用程序中。

2、特征
  • 超过 110 种语言的语法高亮显示(可以导入 TextMate/Sublime Text.tmlanguage 文件)
  • 超过 20 个主题(可以导入 TextMate/Sublime Text .tmtheme 文件)
  • 自动缩进和缩进
  • 可选的命令行
  • 处理大型文档(四百万行似乎是极限!
  • 完全可定制的键绑定,包括 vim 和 Emacs 模式
  • 搜索并替换为正则表达式
  • 突出显示匹配的括号
  • 在软标签和真实标签之间切换
  • 显示隐藏字符
  • 使用鼠标拖放文本
  • 换行
  • 代码折叠
  • 多个光标和选择
  • 实时语法检查器(目前为 JavaScript/CoffeeScript/CSS/XQuery)
  • 剪切、复制和粘贴功能

✒️ Ace 使用及封装

1、安装

使用 pnpm 包管理器,引入 ace-builds 库

    pnpm i ace-builds -D
    pnpm i vue-loader-v16 -D// 引入 ace 报错时需安装
2、引入

引入基础模块,测试ace编辑器基础功能

<template><div class="aceEditor" ref="aceEditor"></div></template><script lang="ts" setup>import{ onBeforeUnmount, onMounted, ref, watch }from'vue';import*as ace from'ace-builds';import"ace-builds/src-noconflict/mode-javascript";// 语言模式import"ace-builds/src-noconflict/theme-monokai"// 主题import"ace-builds/src-noconflict/ext-language_tools";// 语法提示import"ace-builds/src-noconflict/snippets/javascript";// 语法段提示模块</script>
3、配置
const options ={theme:'ace/theme/monokai',// 设置语法高亮主题mode:'ace/mode/javascript',// 设置语法 modetabSize:1,maxLines:25,minLines:25,showPrintMargin:false,fontSize:14,printMarginColumn:20,useWorker:false,showLineNumbers:true,// 显示行号showGutter:true,// 显示行号区域highlightActiveLine:false,highlightSelectedWord:false,// 高亮选中文本readOnly:false,// 控制编辑器是否只读enableSnippets:true,// 启用代码段提示enableLiveAutocompletion:true,// 启用实时自动完成enableBasicAutocompletion:true,// 启用基本自动完成}
4、初始化
constinitEditor=()=>{if(editor) editor.destroy();// 初始化
      editor = ace.edit(aceEditor.value, options);// 切换自动换行
      editor.getSession().setUseWrapMode(true);}onMounted(()=>{initEditor()});

测试 aceEditor 基础封装是否功能正常,方便后续扩展开发。

🔧 Ace 自定义语言扩展

Ace 编辑器本身不支持直接自定义语言,但支持通过扩展语言模式的方式实现对自定义语言的支持。在 Ace 中,语言模式是指将文本分解为标记,定义了每个标记的样式和语法高亮规则,以此来实现语法高亮、代码折叠、自动完成等功能。
想要自定义新增语言模型,首先需要了解如何定义一个 mode (语言模式),可参考官方文档 Ace - The High Performance Code Editor for the Web (c9.io
1、在 node_modules\ace-builds\src-noconflict 下新增一个 mode-mylang.js 的文件,定义语言模式、语言高亮规则及代码提示。

    ace.define('ace/mode/mylang',['require','exports','module','ace/lib/oop','ace/mode/text','ace/mode/custom_highlight_rules'],(require, exports, module)=>{const oop =require('ace/lib/oop');const TextMode =require('ace/mode/text').Mode;const{ MyLangHighlightRules }=require('ace/mode/mylang_highlight_rules');const{ Tokenizer }=require('ace/tokenizer');constMode=function(){this.HighlightRules = MyLangHighlightRules;this.$tokenizer =newTokenizer(newMyLangHighlightRules().getRules());};
    
      oop.inherits(Mode, TextMode);(function(){// 加载css 样式设置,以便控制自定义语言关键词高亮颜色const dom =require('ace/lib/dom');
        dom.importCssString(exports.cssText, exports.cssClass);}).call(Mode.prototype);(function(){// 添加代码提示this.completer ={getCompletions(editor, session, pos, prefix, callback){const wordList =['hello','world','AceEditor','hello world this is AceEditor',];callback(null,
              wordList.map((word)=>({caption: word,value: word,meta:'mylang',// 自定义语言标识})),);},};}.call(Mode.prototype));
    
      exports.Mode = Mode;});

2、接着定于语法高亮规则, 高亮规则里面定义一系列的规则(Rules), 每个规则描述了如何处理输入文本中的单个字符序列。Ace Editor 中的规则是由 Tokenizer 对象处理的。Tokenizer 是 Ace Editor 内置的一种基于正则表达式的解析器,用于将输入文本转换为标记(Token)流。标记是 Ace Editor 中的基本元素,它们由不同类型的 token 组成,例如:keyword、comment、string 等等。

    ace.define('ace/mode/mylang_highlight_rules',['require','exports','module','ace/lib/oop','ace/mode/text_highlight_rules'],(require, exports, module)=>{const oop =require('ace/lib/oop');const{ TextHighlightRules }=require('ace/mode/text_highlight_rules');constMyLangHighlightRules=function(){// 定义高亮规则const keywordList ='let|const|function|world';// 高亮关键词this.$rules ={start:[{token:'keyword',regex:`\\b(?:${keywordList})\\b`,},{token:'string',regex:'".*?"',},{token:'constant',regex:/\b(true|false|null)\b/,},{token:'comment',regex:/\/\/.*$/,},{token:'comment',start:'/\\*',end:'\\*/',},{token:'mylang',regex:'\\b(?:hello|world|AceEditor)\\b',},],};};
    
        oop.inherits(MyLangHighlightRules, TextHighlightRules);
    
        exports.MyLangHighlightRules = MyLangHighlightRules;},);

3、自定义特殊高亮颜色,比如我们想对 true | false | null 进行特殊颜色高亮,只需更具规则中 “token” 属性值,以 .ace_[属性值] 形式定义css。
例:

/* 自定义语言,匹配不同类型关键词高亮颜色 */.ace_constant{color: #FF00FF;font-weight: bold;}

4、最后引入我们自定义语言即可,可直接在option中配置即可

mode:'ace/mode/mylang',

🏁 源码

插件本身还有很多配置和 api , 感兴趣的可以继续探索,本文旨在对初阶自定义功能实现讲解,后续会慢慢更新更深层次自定义方案。

<template><div class="aceEditor" ref="aceEditor"></div></template><script lang="ts" setup>import{ onBeforeUnmount, onMounted, ref, watch }from'vue';import*as ace from'ace-builds';import"ace-builds/src-noconflict/mode-javascript";// 语言模式import"ace-builds/src-noconflict/theme-monokai"// 主题import"ace-builds/src-noconflict/ext-language_tools";// 语法提示import"ace-builds/src-noconflict/snippets/javascript";// 语法段提示模块// 自定义语言import"ace-builds/src-noconflict/mode-mylang";// 此模块需对应目录创建const props =withDefaults(defineProps<{value: string,}>(),{})const emits =defineEmits(['update:value']);leteditor: any =null;const aceEditor = ref<string | Element>('')// 编辑器默认配置项const options ={theme:'ace/theme/monokai',//mode: 'ace/mode/javascript',mode:'ace/mode/mylang',tabSize:1,maxLines:25,minLines:25,showPrintMargin:false,fontSize:14,printMarginColumn:20,useWorker:false,showLineNumbers:true,// 显示行号showGutter:true,// 显示行号区域highlightActiveLine:false,highlightSelectedWord:false,// 高亮选中文本readOnly:false,// 控制编辑器是否只读enableSnippets:true,// 启用代码段enableLiveAutocompletion:true,// 启用实时自动完成enableBasicAutocompletion:true,// 启用基本自动完成}// 初始化编辑器constinitEditor=()=>{if(editor) editor.destroy();// 初始化
      editor = ace.edit(aceEditor.value, options);// 切换自动换行
      editor.getSession().setUseWrapMode(true);// 支持双向绑定
      editor.setValue(props.value ? props.value :"");
      editor.on("change",()=>{emits("update:value", editor.getValue());})}watch(()=> props.value,(newProps)=>{//解决光标移动问题const position = editor.getCursorPosition();
        editor.getSession().setValue(newProps);
        editor.clearSelection();
        editor.moveCursorToPosition(position);});onMounted(()=>{initEditor()});onBeforeUnmount(()=>{
      editor.destroy();});</script><style>.aceEditor {width: 500px;height: 500px;}/* 自定义语言,匹配不同类型关键词高亮颜色 */.ace_constant {color: #FF00FF;
      font-weight: bold;}</style>

📖 相关文档及网站

官网: https://ace.c9.io
GitHub: https://github.com/ajaxorg/ace
Vue3 ace组件: https://github.com/CarterLi/vue3-ace-editor
在线测试: https://ace.c9.io/build/kitchen-sink.html

创作不易,如果本篇文章你觉得还不错的话求个赞😜😜😜


本文转载自: https://blog.csdn.net/Centenario_0/article/details/130332072
版权归原作者 詹姆斯bind 所有, 如有侵权,请联系我们删除。

“【超详细】 对 AceEditor 二次封装 及 自定义扩展语言实现”的评论:

还没有评论