任何密钥后的codemirror自动完成?

时间:2012-12-06 13:02:23

标签: javascript codemirror key-events

我正在尝试添加自定义自动填充功能,我想在用户输入时触发(当然可配置)。我找到了几个代码镜像自动完成的例子:

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');
             }
        });

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

11 个答案:

答案 0 :(得分:22)

对于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 时,您希望弹出窗口关闭,这是一个不应该触发自动完成的字符的特殊情况(您可以考虑一个例子,当您想要显示空行的antocompletion时虽然)。

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

答案 1 :(得分:12)

还要显示自动完成小部件:

onKeyEvent: function (e, s) {
    if (s.type == "keyup") {
        CodeMirror.showHint(e);
    }
}

答案 2 :(得分:11)

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

据我所知,“inputRead”是在“codemirror”中显示“自动完成”的最佳事件。 唯一的缺点是您无法在退格或删除时显示提示。

答案 3 :(得分:11)

可以通过以下方式实现类似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 });
    }
});

答案 4 :(得分:3)

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

答案 5 :(得分:3)

editor.on('keyup', function(){
    CodeMirror.commands.autocomplete(editor);
});

它可能有用

答案 6 :(得分:3)

改变了Oleksandr Pshenychnyy的回答(见here),回答我还没有添加评论

下面的代码只允许在按下字母键时出现自动完成(可能是你想要的,而不是任何键)

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});
    }
});

(这应该在逻辑上有效,但如果有效则可以请一些评论!)

答案 7 :(得分:2)

让我在任何密钥后分享一个包含自动完成(对于hive 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>

答案 8 :(得分:1)

我认为每个人都有自己的用例。我还必须将不同答案的部分结合起来,以做出最适合我的情况的东西。

据我说,我只想显示有关字母,数字和(。)的建议,但按下ctrl键除外。因为有时我会复制或粘贴某些内容,所以不应打开建议。 46 ascii用于(。),我已经将其包含在数字中。

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});
  }
});

记住要包括3件事-

  1. js和css的显示提示- <link rel="stylesheet" href="codemirror/addon/hint/show-hint.css"> <script src="codemirror/addon/hint/show-hint.js"></script>

  2. 您要提示的语言的脚本-例如-javascript <script src="codemirror/addon/hint/javascript-hint.js"></script>

  3. 在初始化代码编辑器时包括此行。我使用了javascript提示。 hint: CodeMirror.hint.javascript

答案 9 :(得分:0)

使用此功能无需CTRL +空格即可自动完成codeMirror。

在show-hint.js中将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);
    }
});

答案 10 :(得分:0)

在这种情况下,更改事件是更好的选择

let inputText = "Some ?string ??? with ?? ? emoji ?"

let textWithoutEmoij = inputText.unicodeScalars
    .filter { !$0.properties.isEmojiPresentation}
    .reduce("") { $0 + String($1) }

print(textWithoutEmoij) // Some string  with   emoji