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();
});