您的位置:首页 > 数据库

codemirror sql

2017-02-04 11:28 351 查看
CodeMirror sql部分智能提示关键字,老板希望可以自己加提示,还能支持 库.表.字段  下面我就说下我具体的做法:


第一步了解 codemirror的实现原理,

   


  看这个很容易看出点啥,codemirror.js 主要是框架和配置类,show-hint.js
主要是显示提示框的类;

      剩下的sql.js是规定了一些常用关键字,好吧其实我们可以在这里改,做下扩展嘛。我选择的是下一个sql-hint.js


第二步看下我写的sql-hint.js吧:

sql-hint.js

[javascript] view
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页面:

[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>  


第三步,我们来看下具体的结果:

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: