使用CodeMirror實現一些自定義的規則
因為專案中需要一個能夠實現自定義規則的文字編輯器,對比了幾個庫,最終還是選用了CodeMirror
CodeMirror的優點
- 文件完善,簡單易懂
- Demo豐富
- 可擴充套件性強
今天我們就來實現一些自定義的語言規則,這些規則只是讓大家對CodeMirror的使用方法有一個初步的瞭解,並不一定實用:
- 自定義關鍵字高亮
- 輸入左括號自動出現右括號
- 左右括號顏色高亮
- 自定義程式碼補全下拉提示框
開工,第一步,我們可以去github上把CodeMirror的程式碼拉下來,或者用npm安裝也可以,然後使用到了裡面的幾個關鍵檔案
// 核心檔案
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
// 自動補全提示框
<script src="../addon/hint/show-hint.js"></script>
<link rel="stylesheet" href="../addon/hint/show-hint.css">
// 左右括號顏色高亮
<script src="../addon/edit/matchbrackets.js"></script>
// textarea內是預設的文字
<textarea id="editor">123 hello world $aaa$</textarea>
複製程式碼
兩個核心檔案是必不可少的,其他的各種addons則是選配
// 定義我們需要高亮的關鍵字
const myHighlightList = [
'hello',
'你好',
'$aaa$'
]
CodeMirror.defineMode('myMode', (config) => {
return {
/**
這個token方法就是用來標亮關鍵字的,
CodeMirror會自上而下,從左往右得遍歷每一個字元,依次呼叫token方法。
stream引數可以用來控制遍歷的粒度,比如我呼叫方法 stream.eatWhile(/\s/),
那麼當前cursor後面所有的空格會被匹配到stream中,stream.current()的值就是所有匹配到的空格。
**/
token: (stream) => {
if (stream.eatSpace()) { return null }
stream.eatWhile(/[\$\w\u4e00-\u9fa5]/)
const cur = stream.current()
const exist = myHighlightList.some((item) => {
return item === cur
})
/**
def 表示藍色,CodeMirror為我們定義了許多顏色,其他還有:
keyword {color: #708;}
atom {color: #219;}
number {color: #164;}
等等,具體可以看codemirror.css檔案中的定義
**/
if (exist) {
return 'def'
}
stream.next()
}
}
})
// 定義想要自動補全的words
const myHintList = [
'hint1',
'hint2',
'ha2',
'ha3'
]
CodeMirror.registerHelper("hint", "myMode", function (cm) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
var start = token.start, end = cur.ch
var str = token.string
// 每次按下 Alt+/ 後會執行這個方法,這裡將當前輸入的字元和myHintList內的文字做字首匹配過濾,實現一邊輸入一邊查詢的功能
const list = myHintList.filter((item) => {
return item.indexOf(str) === 0
})
if (list.length) return {
list: list,
from: CodeMirror.Pos(cur.line, start),
to: CodeMirror.Pos(cur.line, end)
};
});
const editor = CodeMirror.fromTextArea(document.getElementById("editor"), {
lineNumbers: true, // 是否顯示行號
extraKeys: { "Alt-/": "autocomplete" }, // 定義自動補全的快捷鍵
matchBrackets: true, // 是否新增匹配括號高亮
mode: 'myMode' // 自定義的mode名稱
});
// 這裡實現的功能就是按下左括號,自動新增右括號
// 中括號,大括號同理
editor.addKeyMap({
name: 'autoInsertParentheses',
"'('": (cm) => {
const cur = cm.getCursor()
cm.replaceRange('()', cur, cur, '+insert')
cm.doc.setCursor({ line: cur.line, ch: cur.ch + 1 })
}
})
複製程式碼