Preface
這次的副本是基于 ACE DIY 一個 SQL 編輯器剔氏,現(xiàn)階段主要要支持(也就是高亮)所有 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 是字符串或者正則表達式颊糜,用于匹配內(nèi)容的一部分。而 token 用于標識 regex 命中的這部分的高亮規(guī)則秃踩,它可以是字符串或者是函數(shù)(輸入為命中內(nèi)容衬鱼,輸出為規(guī)則標識)。
需要注意的是憔杨,雖然 regex 可以是諸如 [a-zA-Z_$][a-zA-Z0-9_$]*\\b
正則表達式鸟赫,但實踐表明,無論是 /msck/i
還是 (?i)msck
還是 new Regex('msck', 'i')
都無法生效消别,最終經(jīng)過不懈 google抛蚤,發(fā)現(xiàn)忽略大小寫的匹配需要通過如上述代碼中的 caseInsensitive
屬性來設置。
通過閱讀源碼不難發(fā)現(xiàn)寻狂,各個模式下會預先配置一些高亮規(guī)則岁经,通常包括關鍵字、運算符蛇券、類型等等缀壤,而 token 便是用于將內(nèi)容對應到高亮規(guī)則上的。換句話說怀读,token 會作為最終高亮的類別依據(jù)诉位,具體而言,會體現(xiàn)在一個形如 ace_token_name
的 css class 上菜枷。而我們的目的是使得 msck
像關鍵詞那樣高亮苍糠,故直接用模式中已經(jīng)定義的 keyword
作為 token。而如果想要自定義高亮的樣式啤誊,可以將 token 命名成某個自定義的名稱岳瞭,比如 'customized-keyword',而后通過 css 類 ace_customized-keyword
來自定義樣式蚊锹。