codemirror sql

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

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

   

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

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

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

sql-hint.js


[javascript]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 2016/03/22 yc 重写sql-hint.js 
  3.  * @param {Object} mod 
  4.  */  
  5. (function(mod) {  
  6.     if (typeof exports == "object" && typeof module == "object"// CommonJS  
  7.         mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));  
  8.     else if (typeof define == "function" && define.amd) // AMD  
  9.         define(["../../lib/codemirror""../../mode/sql/sql"], mod);  
  10.     else // Plain browser env  
  11.         mod(CodeMirror);  
  12. })(function(CodeMirror) {  
  13.     "use strict";  
  14.     var Pos = CodeMirror.Pos;  
  15.     /** 
  16.      * 从sql.js里获取keyword数组 
  17.      * @param {Object} editor 
  18.      */  
  19.     function getKeywords(editor) {  
  20.         var mode = editor.doc.modeOption;  
  21.         if (mode === "sql") mode = "text/x-sql";  
  22.         return CodeMirror.resolveMode(mode).keywords;  
  23.     };  
  24.     /** 
  25.      * 判断元素item是否存在数组arr中   
  26.      * @param {Object} arr 
  27.      * @param {Object} item 
  28.      */  
  29.     function arrayContains(arr, item) { // 判断元素item是否存在数组arr中    
  30.         if (!Array.prototype.indexOf) {  
  31.             var i = arr.length;  
  32.             while (i--) {  
  33.                 if (arr[i] === item) {  
  34.                     return true;  
  35.                 }  
  36.             }  
  37.             return false;  
  38.         }  
  39.         return arr.indexOf(item) != -1;  
  40.     };  
  41.       
  42.     function hintSql(editor, keywords, tableKeywords, getToken, options) { // 处理hint的核心函数,改名为velocityHint(也可以不做修改)    
  43.         // Find the token at the cursor,获取当前光标指定的字符串    
  44.         var cur = editor.getCursor(),  
  45.             token = getToken(editor, cur),  
  46.             tprop = token;  
  47.         return {  
  48.             list: getCompletions(token, keywords, tableKeywords, options),  
  49.             from: Pos(cur.line, fetchStartPoint(token)), // 字符串拼接的初始位置,这个很重要    
  50.             to: Pos(cur.line, token.end)  
  51.         };  
  52.     };  
  53.     /** 
  54.      * 字符拼接位置 
  55.      * @param {Object} token 
  56.      */  
  57.     function fetchStartPoint(token) {  
  58.         var index = token.string.lastIndexOf("\.");  
  59.         if (index < 0) {  
  60.             return token.start;  
  61.         } else {  
  62.             return token.start + index + 1;  
  63.         }  
  64.         //      return token.start;  
  65.     };  
  66.   
  67.     function sqlHint(editor, options) {  
  68.         var keywords = wordToString(getKeywords(editor)) + CodeMirror.keywords;  
  69.         return hintSql(editor, keywords, CodeMirror.tableKeywords, function(e, cur) {  
  70.             return e.getTokenAt(cur);  
  71.         }, options);  
  72.     };  
  73.     CodeMirror.registerHelper("hint""sql", sqlHint);  
  74.     /** 
  75.      * 得到匹配的关键字数组 
  76.      * @param {Object} token 
  77.      * @param {Object} keywords 
  78.      * @param {Object} tableKeywords 
  79.      * @param {Object} options 
  80.      */  
  81.     function getCompletions(token, keywords, tableKeywords, options) {  
  82.         var found = [],  
  83.             start, pointCount, content = getWord(token.str.string, token.str.end); // found为匹配的数组    
  84.         if (content && content.length) {  
  85.             start = token.string.charAt(0); //字符串首字母  
  86.             content = content.trim().substring(0, content.lenght); //除首字母外的截取  
  87.             pointCount = (start == '\.') ? true : false//判断最后一个字符是否是.  
  88.         }  
  89.         var result = null;  
  90.         if (start && start.trim() != '') { // 必须以$开头,这里暂时不解析${}    
  91.             var regexp = new RegExp("\\b" + content + "\\w+\\.?\\b""gi");  
  92.             if (pointCount && tableKeywords) {  
  93.                 result = tableKeywords.match(regexp);  
  94.             } else {  
  95.                 result = keywords.match(regexp);  
  96.             }  
  97.             console.log('result = ' + result);  
  98.         }  
  99.         if (result && result.length) {  
  100.             for (var i = 0; i < result.length; i++) {  
  101.                 if (!arrayContains(found, result[i]) && content.length <= result[i].length && pointCount) {  
  102.                     if (result[i].charAt(result[i].length-1) == '.') { //如果最后一位是'.'  
  103.                         found.push(result[i].substring(content.lastIndexOf("\.") + 1, result[i].length - 1));  
  104.                     } else {  
  105.                         found.push(result[i].substring(content.lastIndexOf("\.") + 1, result[i].length));  
  106.                     }  
  107.                 } else {  
  108.                     found.push(result[i]);  
  109.                 }  
  110.             }  
  111.         }  
  112.         return found;  
  113.     };  
  114.     /** 
  115.      * 获取当前字符串 
  116.      * @param {Object} str 当前行字符串 
  117.      * @param {Object} end 结束位置 
  118.      */  
  119.     function getWord(str, end) {  
  120.         return str.substring(str.lastIndexOf(' '), end);  
  121.     };  
  122.     /** 
  123.      * 将wordlist拼成字符串 
  124.      * @param {Object} wordlist 
  125.      */  
  126.     function wordToString(wordlist) {  
  127.         var str = '';  
  128.         for (var word in wordlist) {  
  129.             str += word + ' ';  
  130.         }  
  131.         return str;  
  132.     };  
  133. });  

 注释还好啦,你比对下原来的js就会发现实现方法。其实我就是定义了外部变量然后通过赋值拓展的方式实现的。

html页面:

[html]  view plain  copy
 print ?
  1. <!DOCTYPE html>  
  2. <html>  
  3.   
  4.     <head>  
  5.         <meta charset="utf-8" />  
  6.         <title></title>  
  7.     </head>  
  8.     <script type="text/javascript" src="js/jquery-1.7.1.js"></script>  
  9.     <link rel="stylesheet" href="js/codemirror-5.2/theme/3024-day.css">  
  10.     <link type="text/css" rel="stylesheet" href="js/codemirror-5.2/lib/codemirror.css" />  
  11.     <link type="text/css" rel="stylesheet" href="js/codemirror-5.2/addon/hint/show-hint.css" />  
  12.     <script type="text/javascript" src="js/codemirror-5.2/lib/codemirror.js"></script>  
  13.     <script type="text/javascript" src="js/codemirror-5.2/mode/sql/sql.js"></script>  
  14.     <script type="text/javascript" src="js/codemirror-5.2/addon/hint/show-hint.js"></script>  
  15.     <script type="text/javascript" src="js/sql-hint.js"></script>  
  16.   
  17.     <style>  
  18.         .CodeMirror {  
  19.             border: 1px solid black;  
  20.         }  
  21.     </style>  
  22.   
  23.     <body>  
  24.         <h2>SQL编辑器</h2>  
  25.         <form>  
  26.             <textarea id="code" name="code"></textarea>  
  27.         </form>  
  28.         <script>  
  29.             CodeMirror.keywords = "server software ";  
  30.             CodeMirror.tableKeywords = "server.ip server.cache software.conf software.version software.tags.count ";  
  31.             var editor = CodeMirror.fromTextArea(document.getElementById("code"), {  
  32.                 lineNumbers: true,  
  33.                 extraKeys: {  
  34.                     "Ctrl": "autocomplete"  
  35.                 }, //输入s然后ctrl就可以弹出选择项    
  36.                 mode: {  
  37.                     name: "text/x-mysql"  
  38.                 },  
  39.                 theme: "3024-day" //主题    
  40.             });  
  41.             editor.on('change', function() {  
  42.                 editor.showHint(); //满足自动触发自动联想功能  
  43.             });  
  44.         </script>  
  45.     </body>  
  46.   
  47. </html>  




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

    

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值