Javascript 代码镜像在任何键控后自动完成?

Javascript 代码镜像在任何键控后自动完成?,javascript,codemirror,key-events,Javascript,Codemirror,Key Events,我正在尝试添加一个自定义的自动完成,我想在用户输入时触发它(当然是可配置的)。我发现了几个codemirror的自动完成示例: 及 但是这两种方法都会触发特定的键(一个键的控制空间和一个键的控制空间)。注意:这个答案适用于最新版本的CodeMirror onKeyEvent: function(e , s){ if (s.type == "keyup") { consol

我正在尝试添加一个自定义的自动完成,我想在用户输入时触发它(当然是可配置的)。我发现了几个codemirror的自动完成示例:


但是这两种方法都会触发特定的键(一个键的控制空间和一个键的控制空间)。注意:这个答案适用于最新版本的CodeMirror

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

要同时显示自动完成小部件,请执行以下操作:

onKeyEvent: function (e, s) {
    if (s.type == "keyup") {
        CodeMirror.showHint(e);
    }
}
它可能有用

editor.on("inputRead",function(cm,changeObj){
   // hinting logic
})
据我所知,“inputRead”是在“codemirror”中显示“自动完成”的最佳事件。
唯一的缺点是,您无法显示有关退格或删除的提示。

对于5.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});
        }
    });
工作原理:

仅当尚未打开自动完成弹出窗口时,才会打开该弹出窗口(否则,键盘导航将导致在再次选择第一项的情况下重新打开弹出窗口)

当您单击Enter时,您希望弹出窗口关闭,因此这是一个不应该触发自动完成的字符的特殊情况(您可以考虑当您想显示空行的完成)的情况。


最后一个修正是设置<代码>完成>:错误< /代码>,它防止在键入某个单词时,在中间,它自动完成,然后通过反射继续键入。因此,用户总是需要从弹出窗口中选择想要的字符串(即使是单个选项)。.

最类似智能感知的行为可以通过以下方式实现:

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 });
    }
});
var ExcludedIntelliSenseTriggerKeys=
{
“8”:“退格”,
“9”:“选项卡”,
“13”:“输入”,
“16”:“移位”,
“17”:“ctrl”,
“18”:“alt”,
“19”:“暂停”,
“20”:“capslock”,
“27”:“逃跑”,
“33”:“寻呼”,
“34”:“向下翻页”,
“35”:“结束”,
“36”:“家”,
“37”:“左”,
“38”:“向上”,
“39”:“对”,
“40”:“向下”,
“45”:“插入”,
“46”:“删除”,
“91”:“左窗键”,
“92”:“右窗键”,
“93”:“选择”,
“107”:“添加”,
“109”:“减法”,
“110”:“小数点”,
“111”:“分割”,
“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”:“滚动锁”,
“186”:“分号”,
“187”:“相等符号”,
“188”:“逗号”,
“189”:“破折号”,
“190”:“期间”,
“191”:“斜杠”,
“192”:“graveacent”,
“220”:“反斜杠”,
“222”:“引用”
}
EditorInstance.on(“键控”,函数(编辑器,事件)
{
var__Cursor=editor.getDoc().getCursor();
var\uuu Token=editor.getTokenAt(\uu游标);
如果(!editor.state.completionActive&&
!ExcludedIntelliSenseTriggerKeys[(event.keyCode | | event.which).toString()]&&

(|u-Token.type==“tag”|| | u-Token.string==“| | | u-Token.string==”让我来分享一个完整的示例,其中包含任何键控后的自动完成(对于配置单元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>

$(函数(){
initSqlEditor();
initAutoComplete();
});
//初始化sql编辑器
函数initSqlEditor(){
var editor=CodeMirror.fromTextArea(document.getElementById('code'){
自动对焦:对,
外键:{
“选项卡”:“自动完成”
},
提示:CodeMirror.hint.sql,
行号:对,
模式:“文本/x-hive”,
换行:对,
主题:"材料",,
});
on('keyup',函数(编辑器,事件){
//同时键入代码并显示自动完成提示
CodeMirror.commands.autocomplete(编辑器);
});
}
/**
*表名和表中列名的初始化自动完成。
*/
函数initAutoComplete(){
CodeMirror.commands.autocomplete=函数(cmeditor){
CodeMirror.showHint(cmeditor,CodeMirror.hint.sql{
//“completeSingle:false”可防止键入某个单词时出现大小写
在中间,它自动完成,然后继续按反射进行打字。
//所以用户总是需要选择想要的字符串
//从弹出窗口(即使是单个选项)。(从@Oleksandr Pshenychnyy复制)
完全单一:错误,
//有两种方法可以自动完成字段名:
//(1)表名称.字段名称(2)字段名称
//将字段名放在表名中以直接自动完成
//不需要先键入表名。
表:{
“表1”:[“A列”、“B列”、“C列”],
“表2”:[“其他栏1”、“其他栏2”],
“col_A”:[],
“col_B”:[],
“col_C”:[],
“其他专栏1”:[],
“其他专栏2”:[],
}
});
}
}

稍微改变了Oleksandr Pshenychnyy的答案(请参阅),因为我还不能添加注释

下面的代码只允许在按下字母键时自动完成(可能是您在任何键上想要的)

editor.on(“键控”,函数(cm,事件){
如果(!cm.state.completionActive&&/*在自动完成列表中启用键盘导航*/
event.keyCode>64&&event.keyCode<91){//仅当按下字母键时
CodeMirror.commands.autocomplete(cm,null,{completeSingle:false});
}
});

(这在逻辑上应该是可行的,但如果可行的话,请一些人评论一下!)

我认为每个人都有自己的用例。我还必须从不同的答案中拼凑出最适合我的部分

据我所说,我只想对al提出建议
<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>
editor.on("keyup", function (cm, event) {
if (!cm.state.completionActive &&   /*Enables keyboard navigation in autocomplete list*/
     event.keyCode > 64 && event.keyCode < 91){// only when a letter key is pressed
         CodeMirror.commands.autocomplete(cm, null, {completeSingle: false});
    }
});
activeEditor.on("keydown", function (cm, event) {
  if (
    !(event.ctrlKey) &&
    (event.keyCode >= 65 && event.keyCode <= 90) || 
    (event.keyCode >= 97 && event.keyCode <= 122) || 
    (event.keyCode >= 46 && event.keyCode <= 57)
  ) {
    CodeMirror.commands.autocomplete(cm, null, {completeSingle: false});
  }
});
editor.on("inputRead", function(instance) {
    if (instance.state.completionActive) {
            return;
    }
    var cur = instance.getCursor();
    var token = instance.getTokenAt(cur);
    if (token.type && token.type != "comment") {
            CodeMirror.commands.autocomplete(instance);
    }
});
editor.on('change', (cm, event) => {
         editor.execCommand('autocomplete');
        });