2012-12-06 224 views
15

我正在尝试添加自定义自动完成功能,我想要在用户输入时触发(当然可配置)。我发现自动完成的几个例子为codemirror:任何keyup后的codemirror自动完成?

http://codemirror.net/demo/complete.htmlhttp://codemirror.net/demo/xmlcomplete.html

但是这两个触发特定的键(控制-空间之一,“<”的除外),并都使用extraKeys功能来处理事件,但我想从任何键触发。我试过以下几种:

 var editor = CodeMirror.fromTextArea(document.getElementById("code"), 
     { 
      lineNumbers: true, 
      mode: "text/x-mysql", 
      fixedGutter: true, 
      gutter: true, 
//   extraKeys: {"'.'": "autocomplete"} 
      keyup: function(e) 
      { 
       console.log('testing'); 
      }, 
      onkeyup: function(e) 
      { 
       console.log('testing2'); 
      } 
     }); 

但是没有运气。任何关于如何从任何关键事件触发的建议?

回答

2
onKeyEvent: function(e , s){ 
       if (s.type == "keyup") 
       { 
        console.log("test"); 
       } 
      } 
11

还显示自动完成控件:

onKeyEvent: function (e, s) { 
    if (s.type == "keyup") { 
     CodeMirror.showHint(e); 
    } 
} 
3
editor.on('keyup', function(){ 
    CodeMirror.commands.autocomplete(editor); 
}); 

它可以工作

+0

这不提供问题的答案。要批评或要求作者澄清,在他们的帖子下留下评论 - 你总是可以评论你自己的帖子,一旦你有足够的[声誉](http://stackoverflow.com/help/whats-reputation),你会能够[评论任何帖子](http://stackoverflow.com/help/privileges/comment)。 –

+3

这是这个问题的答案!在代码下方添加此代码,每次键入时,它都会触发自动填充事件。 –

11
editor.on("inputRead",function(cm,changeObj){ 
    // hinting logic 
}) 

据我所看到的, “inputRead” 是展现最好的事件“codemirror”中的“自动完成”。 唯一的缺点是你不能在退格或删除时显示提示。

+2

你能否详细说明为什么它是最好的选择?此外,如果您可以展示一些成功实施的示例提示逻辑,那将有助于其他人。 – shmim

+2

“keyup”/“keydown”事件捕获上/下/右/左键。所以“inputRead”是捕捉提示逻辑的最佳方式。 就暗示逻辑而言,它取决于你想要实现它的语言。对于JavaScript,你可以看看“tern.js”。为了构建提示逻辑,在继续之前,需要查看目标语言的标记器,语法分析器和语义。 –

+0

谢谢,我甚至没有意识到这件事。对于提示逻辑,我只是​​使用'cm.showHint({completeSingle:false})'。 – Nickkk

18

对于V5.7,以前提出的解决方案都不适用于我(我认为它们甚至在早期版本中也有错误)。我解决方案

myCodeMirror.on("keyup", function (cm, event) { 
     if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/ 
      event.keyCode != 13) {  /*Enter - do not open autocomplete list just after item has been selected in it*/ 
      CodeMirror.commands.autocomplete(cm, null, {completeSingle: false}); 
     } 
    }); 

它是如何工作的:

这将打开只有当它尚未打开自动完成弹出(否则键盘导航会造成重开与再次选择的第一个项目的弹出) 。

当你点击输入你想要弹出关闭,所以这是一个特殊情况的字符,不应该触发自动完成(你可能会考虑一个情况,当你想显示antocompletion虽然空行)。

然后,最后一个修正是设置completeSingle: false,它可以防止您在输入某个单词时出现的情况,而在中间它会自动完成,并且您继续通过反射进行输入。所以用户总是需要从弹出窗口中选择想要的字符串(即使它是单个选项)。

+1

这个工作原理除了在评论结束时的杂散括号破坏了代码:/ *输入 - 刚刚选择了项目后不要打开自动完成列表* /)<<<本支架 –

+0

@KB。,谢谢,修正了 –

+0

'null'是什么? –

9

最类似IntelliSense的行为可以通过实现这一目标:

var ExcludedIntelliSenseTriggerKeys = 
{ 
    "8": "backspace", 
    "9": "tab", 
    "13": "enter", 
    "16": "shift", 
    "17": "ctrl", 
    "18": "alt", 
    "19": "pause", 
    "20": "capslock", 
    "27": "escape", 
    "33": "pageup", 
    "34": "pagedown", 
    "35": "end", 
    "36": "home", 
    "37": "left", 
    "38": "up", 
    "39": "right", 
    "40": "down", 
    "45": "insert", 
    "46": "delete", 
    "91": "left window key", 
    "92": "right window key", 
    "93": "select", 
    "107": "add", 
    "109": "subtract", 
    "110": "decimal point", 
    "111": "divide", 
    "112": "f1", 
    "113": "f2", 
    "114": "f3", 
    "115": "f4", 
    "116": "f5", 
    "117": "f6", 
    "118": "f7", 
    "119": "f8", 
    "120": "f9", 
    "121": "f10", 
    "122": "f11", 
    "123": "f12", 
    "144": "numlock", 
    "145": "scrolllock", 
    "186": "semicolon", 
    "187": "equalsign", 
    "188": "comma", 
    "189": "dash", 
    "190": "period", 
    "191": "slash", 
    "192": "graveaccent", 
    "220": "backslash", 
    "222": "quote" 
} 

EditorInstance.on("keyup", function(editor, event) 
{ 
    var __Cursor = editor.getDoc().getCursor(); 
    var __Token = editor.getTokenAt(__Cursor); 

    if (!editor.state.completionActive && 
     !ExcludedIntelliSenseTriggerKeys[(event.keyCode || event.which).toString()] && 
     (__Token.type == "tag" || __Token.string == " " || __Token.string == "<" || __Token.string == "/")) 
    { 
     CodeMirror.commands.autocomplete(editor, null, { completeSingle: false }); 
    } 
}); 
+0

你能解释一点点吗?特别是'__Token'条件,它似乎适用于xml(?) – Christian

+0

这个数组包含键码,它不应该触发智能感知下拉,即。功能键,移位或控制。如果引发CodeMirror中的事件,将按照此数组检查按下的键,并且仅当处理程序不在该处时,该处理程序才会继续。这只是为了避免不必要的弹出菜单(我觉得非常烦人)。 –

+0

我添加了“32”:“空格”并删除了“190”:“句点”更像是Visual Studio IntelliSense之类的。 – Jan

1

让我分享任何包含KEYUP后自动完成(对蜂巢SQL)一个完整的例子:

包括脚本和样式:

<link rel="stylesheet" href="/static/codemirror/lib/codemirror.css"> 
<link rel="stylesheet" href="/static/codemirror/theme/material.css"> 
<link rel="stylesheet" href="/static/codemirror/addon/hint/show-hint.css" /> 

<script type="text/javascript" src="/static/codemirror/lib/CodeMirror.js"></script> 
<script type="text/javascript" src="/static/codemirror/mode/sql/sql.js"></script> 
<script type="text/javascript" src="/static/codemirror/addon/hint/show-hint.js"></script> 
<script type="text/javascript" src="/static/codemirror/addon/hint/sql-hint.js"></script> 

HTML:

<textarea id="code" name="code" rows="4" placeholder="" value=""></textarea> 

脚本:

<script> 

    $(function() { 
     initSqlEditor(); 
     initAutoComplete(); 
    }); 

    // init sql editor 
    function initSqlEditor() { 

     var editor = CodeMirror.fromTextArea(document.getElementById('code'), { 
      autofocus: true, 
      extraKeys: { 
       "Tab": "autocomplete" 
      }, 
      hint: CodeMirror.hint.sql, 
      lineNumbers: true, 
      mode: 'text/x-hive', 
      lineWrapping: true, 
      theme: 'material', 
     }); 

     editor.on('keyup', function(editor, event){ 
      // type code and show autocomplete hint in the meanwhile 
      CodeMirror.commands.autocomplete(editor); 
     }); 
    } 

    /** 
    * Init autocomplete for table name and column names in table. 
    */ 
    function initAutoComplete() { 

     CodeMirror.commands.autocomplete = function (cmeditor) { 

      CodeMirror.showHint(cmeditor, CodeMirror.hint.sql, { 

       // "completeSingle: false" prevents case when you are typing some word 
       // and in the middle it is automatically completed and you continue typing by reflex. 
       // So user will always need to select the intended string 
       // from popup (even if it's single option). (copy from @Oleksandr Pshenychnyy) 
       completeSingle: false, 

       // there are 2 ways to autocomplete field name: 
       // (1) table_name.field_name (2) field_name 
       // Put field name in table names to autocomplete directly 
       // no need to type table name first. 
       tables: { 
        "table1": ["col_A", "col_B", "col_C"], 
        "table2": ["other_columns1", "other_columns2"], 
        "col_A": [], 
        "col_B": [], 
        "col_C": [], 
        "other_columns1": [], 
        "other_columns2": [], 
       } 
      }); 
     } 
    } 

</script> 
1

改变阿列克Pshenychnyy的回答有点(见here),回答,因为我不能添加评论

下面的代码也从不必要的情况下

即将停止自动完成
editor.on("keyup", function (cm, event) { 
if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/ 
    event.keyCode != 13 &&   /*Enter - do not open autocomplete list just after item has been selected in it*/ 
    event.keyCode != 16 &&  //not for shift 
    event.keyCode != 17 &&  //not for ctrl 
    event.keyCode != 18 &&  //not for alt 
    event.keyCode != 60 &&  //not for <or> 
    event.keyCode != 32 &&  //not for the space key 
    event.keyCode != 8 &&  //not for the backspace key 
    event.keyCode != 9){  //not for the tab key 
     CodeMirror.commands.autocomplete(cm, null, {completeSingle: false}); 
    } 
}); 

如果这个列表令人讨厌打字给你,或者你认为这个列表还有更多的东西,那么创建一个 函数可能是一个好主意,取决于哪个键被按下,将事件作为参数然后使用它来变为真或假。