ユーザーが入力するたびにトリガーしたいカスタムオートコンプリートを追加しようとしています(もちろん構成可能です)。 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');
}
});
しかし、運がなかった。キーアップイベントからトリガーする方法についての提案はありますか?
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});
}
});
仕組み:
これにより、オートコンプリートポップアップがまだ開かれていない場合にのみ開かれます(そうでない場合、キーボードナビゲーションにより、最初の項目が再度選択された状態でポップアップが再度開かれます)。
Enterをクリックすると、ポップアップを閉じたいので、これはオートコンプリートをトリガーしてはならない文字の特殊なケースです(必要な場合を検討できます)。ただし、空の行のオートコンプリートを表示します)。
次に、最後の修正はcompleteSingle: false
を設定することです。これにより、単語を入力しているときに大文字と小文字が区別されなくなり、途中で自動的に完了し、反射的に入力を続けます。したがって、ユーザーは常にポップアップから目的の文字列を選択する必要があります(単一のオプションであっても)。
オートコンプリートウィジェットも表示するには:
onKeyEvent: function (e, s) {
if (s.type == "keyup") {
CodeMirror.showHint(e);
}
}
editor.on("inputRead",function(cm,changeObj){
// hinting logic
})
私が見た限りでは、「inputRead」は「codemirror」で「オートコンプリート」を表示するのに最適なイベントです。唯一の欠点は、バックスペースにヒントを表示したり、削除したりできないことです。
最も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);
});
それはうまくいくかもしれません
キーアップ後にオートコンプリート(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>
この関数を使用して、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);
}
});
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});
}
});
(これは論理的に機能するはずですが、これが機能するかどうかコメントしてください!)
誰もが独自のユースケースを持っていると思います。また、自分のケースに最適なものを作成するために、さまざまな回答のパーツをクラブする必要がありました。
私によると、Ctrlキーを押した場合を除いて、アルファベット、数字、(。)のみで提案を表示したいと思います。時々私は何かをコピーしたり貼り付けたりするので、それは提案を開くべきではありません。 46アスキーは私が数字で含めた(。)のためのものです。
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つのことを含めるように覚えておいてください-
ショーヒントのjsとcss -<link rel="stylesheet" href="codemirror/addon/hint/show-hint.css"> <script src="codemirror/addon/hint/show-hint.js"></script>
ヒントが必要な言語のスクリプト--forex --javascript <script src="codemirror/addon/hint/javascript-hint.js"></script>
コードエディタを初期化するときにこの行を含めます。私はjavascriptヒントを使用しました。 hint: CodeMirror.hint.javascript