define( ['jquery', 'Bacon'], function($, Bacon) { function unquoted(name) { var start = 0, end = name.length; if (name.length >= 1) { if (name.charAt(0) == '"') { start = 1; if (name.length > 1 && name.charAt(name.length - 1) == '"') { end = name.length - 1; } } return name.substring(start, end); } return name; } function setCaret(e, num) { e.selectionStart = e.selectionEnd = num; } var completer = (function (input_element, dropdown) { var triggerStart = '#', triggerEnd = ' ', dropdown_raw = dropdown[0], options_bus = new Bacon.Bus(), options = [], selected_index = -1, input_element_raw = input_element[0], completion_start = 0, completion_end = 0, minimum_length = 1; // turn off the browser's autocomplete input_element.attr('autocomplete', 'off'); //$('.ui-autocomplete').css('width', '10px'); options_bus.onValue(function update_options(new_options) { options = new_options; }); function completions(text) { var ret = [], noquotes = unquoted(text.toLowerCase()); for (var name in options) { if (name.toLowerCase().indexOf(noquotes) === 0) { ret.push(name); } } return ret; } function oninput(text, cursor) { // #this is a # // ^ // // #this is a #t // ^ // // #this and #that then #he // ^ var hash = text.slice(0, cursor).lastIndexOf(triggerStart); // TODO check if current completion has been invalidated _invalidateSelection(); dropdown.hide(); dropdown_raw.innerHTML = ""; // remove all elements if (hash == -1) { return; } var space = text.slice(hash).indexOf(triggerEnd); space = space == -1 ? text.length : space; if (space < cursor) { return; } completion_start = hash + 1; completion_end = space; var string = text.slice(completion_start, completion_end); if (string.length < minimum_length) { return; } // [hash] [cursor] [space/end] completions(string).forEach(function(name) { dropdown.append($('