simple-hint.js
76 lines
| 3.0 KiB
| application/javascript
|
JavascriptLexer
Brian Granger
|
r5941 | (function() { | ||
CodeMirror.simpleHint = function(editor, getHints) { | ||||
// We want a single cursor position. | ||||
if (editor.somethingSelected()) return; | ||||
Matthias BUSSONNIER
|
r8053 | //don't show completion if the token is empty | ||
var tempToken = editor.getTokenAt(editor.getCursor()); | ||||
if(!(/[\S]/gi.test(tempToken.string))) return; | ||||
Brian Granger
|
r5941 | var result = getHints(editor); | ||
if (!result || !result.list.length) return; | ||||
var completions = result.list; | ||||
function insert(str) { | ||||
editor.replaceRange(str, result.from, result.to); | ||||
} | ||||
// When there is only one completion, use it directly. | ||||
if (completions.length == 1) {insert(completions[0]); return true;} | ||||
// Build the select widget | ||||
var complete = document.createElement("div"); | ||||
complete.className = "CodeMirror-completions"; | ||||
var sel = complete.appendChild(document.createElement("select")); | ||||
// Opera doesn't move the selection when pressing up/down in a | ||||
// multi-select, but it does properly support the size property on | ||||
// single-selects, so no multi-select is necessary. | ||||
if (!window.opera) sel.multiple = true; | ||||
for (var i = 0; i < completions.length; ++i) { | ||||
var opt = sel.appendChild(document.createElement("option")); | ||||
opt.appendChild(document.createTextNode(completions[i])); | ||||
} | ||||
sel.firstChild.selected = true; | ||||
sel.size = Math.min(10, completions.length); | ||||
var pos = editor.cursorCoords(); | ||||
complete.style.left = pos.x + "px"; | ||||
complete.style.top = pos.yBot + "px"; | ||||
document.body.appendChild(complete); | ||||
Matthias BUSSONNIER
|
r8053 | // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. | ||
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); | ||||
if(winW - pos.x < sel.clientWidth) | ||||
complete.style.left = (pos.x - sel.clientWidth) + "px"; | ||||
Brian Granger
|
r5941 | // Hack to hide the scrollbar. | ||
if (completions.length <= 10) | ||||
complete.style.width = (sel.clientWidth - 1) + "px"; | ||||
var done = false; | ||||
function close() { | ||||
if (done) return; | ||||
done = true; | ||||
complete.parentNode.removeChild(complete); | ||||
} | ||||
function pick() { | ||||
insert(completions[sel.selectedIndex]); | ||||
close(); | ||||
setTimeout(function(){editor.focus();}, 50); | ||||
} | ||||
CodeMirror.connect(sel, "blur", close); | ||||
CodeMirror.connect(sel, "keydown", function(event) { | ||||
var code = event.keyCode; | ||||
// Enter | ||||
if (code == 13) {CodeMirror.e_stop(event); pick();} | ||||
// Escape | ||||
else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();} | ||||
else if (code != 38 && code != 40) { | ||||
close(); editor.focus(); | ||||
Matthias BUSSONNIER
|
r8053 | // Pass the event to the CodeMirror instance so that it can handle things like backspace properly. | ||
editor.triggerOnKeyDown(event); | ||||
Brian Granger
|
r5941 | setTimeout(function(){CodeMirror.simpleHint(editor, getHints);}, 50); | ||
} | ||||
}); | ||||
CodeMirror.connect(sel, "dblclick", pick); | ||||
sel.focus(); | ||||
// Opera sometimes ignores focusing a freshly created node | ||||
if (window.opera) setTimeout(function(){if (!done) sel.focus();}, 100); | ||||
return true; | ||||
}; | ||||
})(); | ||||