codemirror sql
2017-02-04 11:28
351 查看
CodeMirror sql部分智能提示关键字,老板希望可以自己加提示,还能支持 库.表.字段 下面我就说下我具体的做法:
看这个很容易看出点啥,codemirror.js 主要是框架和配置类,show-hint.js
主要是显示提示框的类;
剩下的sql.js是规定了一些常用关键字,好吧其实我们可以在这里改,做下扩展嘛。我选择的是下一个sql-hint.js
plain copy
print?
/**
* 2016/03/22 yc 重写sql-hint.js
* @param {Object} mod
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
/**
* 从sql.js里获取keyword数组
* @param {Object} editor
*/
function getKeywords(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).keywords;
};
/**
* 判断元素item是否存在数组arr中
* @param {Object} arr
* @param {Object} item
*/
function arrayContains(arr, item) { // 判断元素item是否存在数组arr中
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
};
function hintSql(editor, keywords, tableKeywords, getToken, options) { // 处理hint的核心函数,改名为velocityHint(也可以不做修改)
// Find the token at the cursor,获取当前光标指定的字符串
var cur = editor.getCursor(),
token = getToken(editor, cur),
tprop = token;
return {
list: getCompletions(token, keywords, tableKeywords, options),
from: Pos(cur.line, fetchStartPoint(token)), // 字符串拼接的初始位置,这个很重要
to: Pos(cur.line, token.end)
};
};
/**
* 字符拼接位置
* @param {Object} token
*/
function fetchStartPoint(token) {
var index = token.string.lastIndexOf("\.");
if (index < 0) {
return token.start;
} else {
return token.start + index + 1;
}
// return token.start;
};
function sqlHint(editor, options) {
var keywords = wordToString(getKeywords(editor)) + CodeMirror.keywords;
return hintSql(editor, keywords, CodeMirror.tableKeywords, function(e, cur) {
return e.getTokenAt(cur);
}, options);
};
CodeMirror.registerHelper("hint", "sql", sqlHint);
/**
* 得到匹配的关键字数组
* @param {Object} token
* @param {Object} keywords
* @param {Object} tableKeywords
* @param {Object} options
*/
function getCompletions(token, keywords, tableKeywords, options) {
var found = [],
start, pointCount, content = getWord(token.str.string, token.str.end); // found为匹配的数组
if (content && content.length) {
start = token.string.charAt(0); //字符串首字母
content = content.trim().substring(0, content.lenght); //除首字母外的截取
pointCount = (start == '\.') ? true : false; //判断最后一个字符是否是.
}
var result = null;
if (start && start.trim() != '') { // 必须以$开头,这里暂时不解析${}
var regexp = new RegExp("\\b" + content + "\\w+\\.?\\b", "gi");
if (pointCount && tableKeywords) {
result = tableKeywords.match(regexp);
} else {
result = keywords.match(regexp);
}
console.log('result = ' + result);
}
if (result && result.length) {
for (var i = 0; i < result.length; i++) {
if (!arrayContains(found, result[i]) && content.length <= result[i].length && pointCount) {
if (result[i].charAt(result[i].length-1) == '.') { //如果最后一位是'.'
found.push(result[i].substring(content.lastIndexOf("\.") + 1, result[i].length - 1));
} else {
found.push(result[i].substring(content.lastIndexOf("\.") + 1, result[i].length));
}
} else {
found.push(result[i]);
}
}
}
return found;
};
/**
* 获取当前字符串
* @param {Object} str 当前行字符串
* @param {Object} end 结束位置
*/
function getWord(str, end) {
return str.substring(str.lastIndexOf(' '), end);
};
/**
* 将wordlist拼成字符串
* @param {Object} wordlist
*/
function wordToString(wordlist) {
var str = '';
for (var word in wordlist) {
str += word + ' ';
}
return str;
};
});
注释还好啦,你比对下原来的js就会发现实现方法。其实我就是定义了外部变量然后通过赋值拓展的方式实现的。
[html] view
plain copy
print?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
<link rel="stylesheet" href="js/codemirror-5.2/theme/3024-day.css">
<link type="text/css" rel="stylesheet" href="js/codemirror-5.2/lib/codemirror.css" />
<link type="text/css" rel="stylesheet" href="js/codemirror-5.2/addon/hint/show-hint.css" />
<script type="text/javascript" src="js/codemirror-5.2/lib/codemirror.js"></script>
<script type="text/javascript" src="js/codemirror-5.2/mode/sql/sql.js"></script>
<script type="text/javascript" src="js/codemirror-5.2/addon/hint/show-hint.js"></script>
<script type="text/javascript" src="js/sql-hint.js"></script>
<style>
.CodeMirror {
border: 1px solid black;
}
</style>
<body>
<h2>SQL编辑器</h2>
<form>
<textarea id="code" name="code"></textarea>
</form>
<script>
CodeMirror.keywords = "server software ";
CodeMirror.tableKeywords = "server.ip server.cache software.conf software.version software.tags.count ";
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
extraKeys: {
"Ctrl": "autocomplete"
}, //输入s然后ctrl就可以弹出选择项
mode: {
name: "text/x-mysql"
},
theme: "3024-day" //主题
});
editor.on('change', function() {
editor.showHint(); //满足自动触发自动联想功能
});
</script>
</body>
</html>
第一步了解 codemirror的实现原理,
看这个很容易看出点啥,codemirror.js 主要是框架和配置类,show-hint.js
主要是显示提示框的类;
剩下的sql.js是规定了一些常用关键字,好吧其实我们可以在这里改,做下扩展嘛。我选择的是下一个sql-hint.js
第二步看下我写的sql-hint.js吧:
sql-hint.js
[javascript] viewplain copy
print?
/**
* 2016/03/22 yc 重写sql-hint.js
* @param {Object} mod
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
/**
* 从sql.js里获取keyword数组
* @param {Object} editor
*/
function getKeywords(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).keywords;
};
/**
* 判断元素item是否存在数组arr中
* @param {Object} arr
* @param {Object} item
*/
function arrayContains(arr, item) { // 判断元素item是否存在数组arr中
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
};
function hintSql(editor, keywords, tableKeywords, getToken, options) { // 处理hint的核心函数,改名为velocityHint(也可以不做修改)
// Find the token at the cursor,获取当前光标指定的字符串
var cur = editor.getCursor(),
token = getToken(editor, cur),
tprop = token;
return {
list: getCompletions(token, keywords, tableKeywords, options),
from: Pos(cur.line, fetchStartPoint(token)), // 字符串拼接的初始位置,这个很重要
to: Pos(cur.line, token.end)
};
};
/**
* 字符拼接位置
* @param {Object} token
*/
function fetchStartPoint(token) {
var index = token.string.lastIndexOf("\.");
if (index < 0) {
return token.start;
} else {
return token.start + index + 1;
}
// return token.start;
};
function sqlHint(editor, options) {
var keywords = wordToString(getKeywords(editor)) + CodeMirror.keywords;
return hintSql(editor, keywords, CodeMirror.tableKeywords, function(e, cur) {
return e.getTokenAt(cur);
}, options);
};
CodeMirror.registerHelper("hint", "sql", sqlHint);
/**
* 得到匹配的关键字数组
* @param {Object} token
* @param {Object} keywords
* @param {Object} tableKeywords
* @param {Object} options
*/
function getCompletions(token, keywords, tableKeywords, options) {
var found = [],
start, pointCount, content = getWord(token.str.string, token.str.end); // found为匹配的数组
if (content && content.length) {
start = token.string.charAt(0); //字符串首字母
content = content.trim().substring(0, content.lenght); //除首字母外的截取
pointCount = (start == '\.') ? true : false; //判断最后一个字符是否是.
}
var result = null;
if (start && start.trim() != '') { // 必须以$开头,这里暂时不解析${}
var regexp = new RegExp("\\b" + content + "\\w+\\.?\\b", "gi");
if (pointCount && tableKeywords) {
result = tableKeywords.match(regexp);
} else {
result = keywords.match(regexp);
}
console.log('result = ' + result);
}
if (result && result.length) {
for (var i = 0; i < result.length; i++) {
if (!arrayContains(found, result[i]) && content.length <= result[i].length && pointCount) {
if (result[i].charAt(result[i].length-1) == '.') { //如果最后一位是'.'
found.push(result[i].substring(content.lastIndexOf("\.") + 1, result[i].length - 1));
} else {
found.push(result[i].substring(content.lastIndexOf("\.") + 1, result[i].length));
}
} else {
found.push(result[i]);
}
}
}
return found;
};
/**
* 获取当前字符串
* @param {Object} str 当前行字符串
* @param {Object} end 结束位置
*/
function getWord(str, end) {
return str.substring(str.lastIndexOf(' '), end);
};
/**
* 将wordlist拼成字符串
* @param {Object} wordlist
*/
function wordToString(wordlist) {
var str = '';
for (var word in wordlist) {
str += word + ' ';
}
return str;
};
});
注释还好啦,你比对下原来的js就会发现实现方法。其实我就是定义了外部变量然后通过赋值拓展的方式实现的。
html页面:
[html] viewplain copy
print?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
<link rel="stylesheet" href="js/codemirror-5.2/theme/3024-day.css">
<link type="text/css" rel="stylesheet" href="js/codemirror-5.2/lib/codemirror.css" />
<link type="text/css" rel="stylesheet" href="js/codemirror-5.2/addon/hint/show-hint.css" />
<script type="text/javascript" src="js/codemirror-5.2/lib/codemirror.js"></script>
<script type="text/javascript" src="js/codemirror-5.2/mode/sql/sql.js"></script>
<script type="text/javascript" src="js/codemirror-5.2/addon/hint/show-hint.js"></script>
<script type="text/javascript" src="js/sql-hint.js"></script>
<style>
.CodeMirror {
border: 1px solid black;
}
</style>
<body>
<h2>SQL编辑器</h2>
<form>
<textarea id="code" name="code"></textarea>
</form>
<script>
CodeMirror.keywords = "server software ";
CodeMirror.tableKeywords = "server.ip server.cache software.conf software.version software.tags.count ";
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
extraKeys: {
"Ctrl": "autocomplete"
}, //输入s然后ctrl就可以弹出选择项
mode: {
name: "text/x-mysql"
},
theme: "3024-day" //主题
});
editor.on('change', function() {
editor.showHint(); //满足自动触发自动联想功能
});
</script>
</body>
</html>
第三步,我们来看下具体的结果:
相关文章推荐
- Oracle基础 11 约束 constraints
- mysql 5.6 enable GTID replication
- Oracle基础 10 表 table
- 数据库设计三大范式
- Oracle基础 09 概要文件 profile
- Oracle基础 08 用户角色 user/role
- sql 学习相关问题
- Oracle基础 07 参数文件 pfile/spfile
- Oracle基础 06 控制文件 controlfile
- Oracle基础 05 联机日志 redolog
- mysql从库Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'报错处理
- MySQL数据库的三大范式定义,作用—------你所期待的最佳答案
- Oracle基础 04 归档日志 archivelog
- Oracle中字符和字符串的截取
- Oracle基础 03 回滚表空间 undo
- Oracle基础 02 临时表空间 temp
- mysql取某表中数据的随机的方法
- Oracle基础 01 表空间 tablespace
- SqlServer 查看被锁的表和解除被锁的表
- PL/SQL Developer 连接 Oracle