автозаполнение codemirror после любого ключа?

Я работаю над попыткой добавить пользовательское автозаполнение, которое я хочу запускать всякий раз, когда пользователь вводит (настраивается, конечно). Я нашел пару примеров автозаполнения для codemirror:

http://codemirror.net/demo/complete.html и http://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?

9 ответов


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

для версии 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});
        }
    });

как работает:

это открывает всплывающее окно автозаполнения, только если оно еще не открыто (в противном случае клавиатура-навигация вызвала бы повторное открытие всплывающего окна с 1-м выбранным элементом).

при нажатии Enter вы хотите, чтобы всплывающее окно, чтобы закрыть это частный случай символа, который не должен вызывать автозаполнение (вы можете рассмотреть случай, когда вы хотите показать antocompletion для пустой строки).

тогда последнее исправление-установка completeSingle: false что предотвращает случай, когда вы вводите какое-то слово, и в середине оно автоматически завершается, и вы продолжаете печатать рефлекторно. Поэтому пользователю всегда нужно будет выбрать нужную строку из всплывающего окна (даже если это один вариант).


отображение виджет autocomplete:

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

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

насколько я видел, "inputRead" - лучшее событие для отображения" автозавершений "в"codemirror". Единственным недостатком является то, что вы не можете показывать подсказки в backspace или удалять.


самое 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 });
    }
});

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

он работает


немного изменил ответ Александра Пшеничного(см. здесь), ответа, как я не могу добавить комментарий

приведенный ниже код позволяет автозаполнение только при нажатии клавиши с буквой (возможно, то, что вы хотите вместо любой клавиши)

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

(это должно работать логически, но могут ли некоторые прокомментировать, если это работает или нет !)


позвольте мне поделиться полным примером, который содержит автозаполнение (для hive sql) после любого keyup:

включить скрипты и стили:

<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>

Я думаю, что у каждого свои варианты использования. Мне также пришлось собирать части из разных ответов, чтобы сделать что-то лучшее для моего случая.

по моему мнению, я хочу показывать предложения только по алфавитам, цифрам и (.) за исключением нажатия клавиши 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});
  }
});

do remeber, чтобы включить 3 вещи -

  1. js и css подсказки шоу - <link rel="stylesheet" href="codemirror/addon/hint/show-hint.css"> <script src="codemirror/addon/hint/show-hint.js"></script>

  2. скрипт для языка вы хотите подсказку для-для ex-javascript <script src="codemirror/addon/hint/javascript-hint.js"></script>

  3. включите эту строку при инициализации редактора кода. Я использовал подсказку javascript. hint: CodeMirror.hint.javascript