26

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

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

但是这两个都在特定键上触发(一个是 Control-Space,另一个是 '<')并且都使用该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');
             }
        });

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

4

11 回答 11

32

对于 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时,您希望关闭弹出窗口,因此这是不应触发自动补全的字符的特殊情况(但您可能会考虑一种情况,即您希望为空行显示反补全)。

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

于 2015-10-08T17:01:42.083 回答
14

可以通过以下方式实现最类似于 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 });
    }
});
于 2015-11-25T05:21:04.497 回答
13

要同时显示自动完成小部件:

onKeyEvent: function (e, s) {
    if (s.type == "keyup") {
        CodeMirror.showHint(e);
    }
}
于 2013-07-20T13:49:57.370 回答
11
editor.on("inputRead",function(cm,changeObj){
   // hinting logic
})

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

于 2015-05-21T09:35:17.413 回答
5

使用此功能无需 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);
    }
});
于 2019-01-26T11:27:22.980 回答
4

让我分享一个完整的示例,其中包含任何 keyup 之后的自动完成(用于 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>

网页:

<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>
于 2016-12-07T05:50:07.913 回答
4

我认为每个人都有自己的用例。我还必须从不同的答案中挑选部分来制作最适合我的情况的东西。

据我说,我只想显示关于字母、数字和 (.) 的建议,但按下 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});
  }
});

请记住包括三件事 -

  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

于 2018-07-11T09:41:30.620 回答
3
editor.on('keyup', function(){
    CodeMirror.commands.autocomplete(editor);
});

它可能有效

于 2015-03-19T06:30:55.590 回答
3

稍微改变了 Oleksandr Pshenychnyy 的回答(见这里),回答因为我还不能添加评论

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

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

(这应该是合乎逻辑的,但是如果这可行的话,有些人可以评论一下!)

于 2017-10-22T10:32:53.883 回答
2

注意:此答案不适用于最新版本的 CodeMirror。

onKeyEvent: function(e , s){
                if (s.type == "keyup")
                {
                    console.log("test");   
                }
            }
于 2012-12-06T21:54:51.457 回答
1

对于这种情况,更改事件是更好的选择

editor.on('change', (cm, event) => {
         editor.execCommand('autocomplete');
        });
于 2020-08-14T15:50:02.317 回答