Codemirror是一個不錯的Web代碼編輯庫,可以方便簡單的集成。沒有自動提示功能的代碼編輯器是沒有靈魂的,Codemirror的自動提示功能是使用show-hint庫進行的,我們可以調用showHint方法或者autoComplete方法來顯示提示框。
普遍的用法:
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/x-java",
lineNumbers: true,
theme: "dracula",
matchBrackets: true, //括號匹配
//readOnly: true,
});
假設我們在Vue裏面使用它做一個SQL編輯器,我們可以安裝Vue-Codemirror更方便的使用組件。
npm i vue-codemirror --save
然後引用這個組件:
import { codemirror } from "vue-codemirror";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/idea.css";
import "codemirror/theme/panda-syntax.css";
import "codemirror/addon/hint/show-hint.css";
require("codemirror/lib/codemirror");
require("codemirror/mode/sql/sql");
require("codemirror/addon/hint/show-hint");
require("codemirror/addon/hint/sql-hint");
這裏面idea.css
和panda-syntax.css
都是主題樣式文件,更多主題可以看這裏:主題
<codemirror ref="editQuerySQL" v-model="query.sql" :options="cmOptions"></codemirror>
cmOptions: {
tabSize: 4,
lineNumbers: true,
line: true,
indentWithTabs: true,
smartIndent: true,
autofocus: false,
mode: "text/x-mariadb",
theme: "idea",
hintOptions: {
completeSingle: false
}
},
//顯示提示
this.editQuerySQL.on("cursorActivity", () => {
this.editQuerySQL.showHint();
});
mode是代碼類型,比如SQL,JS,HTML等,Codemirror支持超過100種語言,更多語言。
如果我們需要動態改變主題:
this.editQuerySQL.setOption("theme", this.editorSQLTheme);
現在編輯器就可以使用了:
- 問題一
如果選中了提示框裏面的詞(使用鼠標或者回車鍵)之後會無法刪除,不能直接使用刪除鍵進行刪除,而只能使用鼠標選中整個刪除詞。
默認情況下,如果我們輸入了提示詞列表的某個首字母,會自動認爲我們選中了某個提示詞。
例如,現在我們使用了sql-hint
,如果我們輸入了S,不使用鼠標選中提示框裏的任何詞,它會將select關鍵字認爲是我們選擇的。但是這樣非常困擾人,因爲我們很可能是想輸入其他以S開頭的某個任意的詞語。
上面這兩個現象都是由於一個默認配置引起的。
在Codemirror官方文檔show-hint部分可以看到
這個completeSingle
的作用是當只敲擊了一個單個的字母時,在不打開提示框的情況下,是否認爲這個字母是提示語的一部分。默認爲true。
如果是true,那麼如果我們只輸入了S,輸入結束的時候會變成Select。如果爲False,那麼就不會這樣,而是正常的和其他代碼編輯器一樣單個處理。
所以我們將其設置爲 fasle:
hintOptions: {
completeSingle: false
}
這樣以上兩個問題都解決了。
問題二:
輸入結束會出現這樣的情況:
這是因爲我們使用的是cursorActivity事件:
可以看到cursorActivity
事件:當光標或選區移動或對編輯器內容進行任何更改時,將觸發該事件。
我們選擇完一個關鍵詞,光標就發生了變化,所以會觸發提示的顯示。
還有一個inputRead
事件:每當從隱藏的文本區域中讀取新輸入(由用戶鍵入或粘貼)時,就會觸發。
我們使用這個事件,就會只有我們的手動操作纔會觸發提示框顯示。
this.editQuerySQL.on("inputRead", () => {
this.editQuerySQL.showHint();
});