CodeMirror入門

使用CodeMirror實現一些自定義的規則

由於項目中須要一個可以實現自定義規則的文本編輯器,對比了幾個庫,最終仍是選用了CodeMirrorcss

CodeMirror的優勢git

  1. 文檔完善,簡單易懂
  2. Demo豐富
  3. 可擴展性強

今天咱們就來實現一些自定義的語言規則,這些規則只是讓你們對CodeMirror的使用方法有一個初步的瞭解,並不必定實用:github

  1. 自定義關鍵字高亮
  2. 輸入左括號自動出現右括號
  3. 左右括號顏色高亮
  4. 自定義代碼補全下拉提示框

開工,第一步,咱們能夠去github上把CodeMirror的代碼拉下來,或者用npm安裝也能夠,而後使用到了裏面的幾個關鍵文件npm

1
2
3
4
5
6
7
8
9
10
11
// 核心文件
<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則是選配編輯器

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 定義咱們須要高亮的關鍵字
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 })
}
})
相關文章
相關標籤/搜索