ACE 编辑器高亮自定义关键词
Preface这次的副本是基于 ACE DIY 一个 SQL 编辑器,现阶段主要要支持所有 Hive 关键词。Analysis众所周知,ACE 默认支持了很多模式(比如 sql、JavaScript等等),但这些模式只会高亮特定的一些关键词,当我想要高亮额外的关键字时(比如我在 sql 模式想高亮 HIVE 中的 MSCK),则需要配置一番。Show Code比如,当我们在一个 VUE APP 中
Preface
这次的副本是基于 ACE DIY 一个 SQL 编辑器,现阶段主要要支持(也就是高亮)所有 Hive 关键词。
Analysis
众所周知,ACE 默认支持了很多模式(比如 sql、JavaScript等等),但这些模式只会高亮特定的一些关键词,当我想要高亮额外的关键字时(比如我在 sql
模式想高亮 HIVE
中的 MSCK
),则需要配置一番。
Show Code
比如,当我们在一个 VUE APP 中(Vue2),yarn add ace-builds
安装了 ACE 之后,一个在 sql 模式
、sqlserver 主题
下,扩充了 MSCK
关键字的例子如下:
<template>
<div
ref="editor"
style="height: 400px; width: 500px"
></div>
</template>
<script>
import ace from 'ace-builds';
import 'ace-builds/webpack-resolver';
import 'ace-builds/src-noconflict/mode-sql';
import 'ace-builds/src-noconflict/theme-sqlserver';
export default {
data: () => ({
editor: null,
}),
mounted() {
this.initializeEditor();
},
beforeDestroy() {
if(this.editor){
this.editor.destroy();
this.editor.container.remove();
}
},
methods: {
initializeEditor() {
this.editor = ace.edit(this.$refs['editor'], {
theme: 'ace/theme/sqlserver',
});
const session = this.editor.session;
session.setMode('ace/mode/sql', function () {
const rules = session.$mode.$highlightRules.getRules();
for (const stateName in rules) {
rules[stateName].unshift({
token: 'keyword',
regex: 'msck',
caseInsensitive: true,
});
}
// force recreation of tokenizer
session.$mode.$tokenizer = null;
session.bgTokenizer.setTokenizer(session.$mode.getTokenizer());
// force re-highlight whole document
session.bgTokenizer.start(0);
});
},
},
};
</script>
其中,关键部分在于:
session.setMode('ace/mode/sql', function () {
const rules = session.$mode.$highlightRules.getRules();
for (const stateName in rules) {
rules[stateName].unshift({
token: 'keyword',
regex: 'msck',
caseInsensitive: true,
});
}
// force recreation of tokenizer
session.$mode.$tokenizer = null;
session.bgTokenizer.setTokenizer(session.$mode.getTokenizer());
// force re-highlight whole document
session.bgTokenizer.start(0);
});
简单来说,regex 是字符串或者正则表达式,用于匹配内容的一部分。而 token 用于标识 regex 命中的这部分的高亮规则,它可以是字符串或者是函数(输入为命中内容,输出为规则标识)。
需要注意的是,虽然 regex 可以是诸如 [a-zA-Z_$][a-zA-Z0-9_$]*\\b
正则表达式,但实践表明,无论是 /msck/i
还是 (?i)msck
还是 new Regex('msck', 'i')
都无法生效,最终经过不懈 google,发现忽略大小写的匹配需要通过如上述代码中的 caseInsensitive
属性来设置。
通过阅读源码不难发现,各个模式下会预先配置一些高亮规则,通常包括关键字、运算符、类型等等,而 token 便是用于将内容对应到高亮规则上的。换句话说,token 会作为最终高亮的类别依据,具体而言,会体现在一个形如 ace_token_name
的 css class 上。而我们的目的是使得 msck
像关键词那样高亮,故直接用模式中已经定义的 keyword
作为 token。而如果想要自定义高亮的样式,可以将 token 命名成某个自定义的名称,比如 ‘customized-keyword’,而后通过 css 类 ace_customized-keyword
来自定义样式。
Reference
更多推荐
所有评论(0)