(function($) {
var readline_offset = search_offset = 0;
var input, input_prompt, original_prompt, startCompletion;
var readline_history = [];
var original_autocomplete_options = {
close: function(event, ui) { exit_search_history(); return true; },
disabled: true,
source: function(request, response) {
return response(get_search_history(request.term));
}
};
var clear_line = function () { input.val(''); };
var previous_line = function () {
var val = readline_history[readline_history.length - 1 - readline_offset];
if (val) { readline_offset +=1; }
input.val(val);
return false;
};
var next_line = function () {
var val = readline_history[readline_history.length + 1 - readline_offset];
if (val) { readline_offset -=1; }
input.val(val);
return false;
};
var search_history = function() {
input.autocomplete('enable');
original_prompt = input_prompt.text();
input_prompt.text("(search-history):");
}
var get_search_history = function(term) {
var results = [];
$.each(readline_history.reverse(), function(key,value) {
(value.indexOf(term) != -1) && results.push(value);
});
return results;
};
var exit_search_history = function() {
input.autocomplete('disable');
$('ul.ui-autocomplete').hide();
input_prompt.text(original_prompt);
};
var tab_complete = function() {
input.autocomplete('enable');
startCompletion(input.val());
return false;
};
// Options:
// * startCompletion: function to start a tab completion, given the element's current value
// * autocompleteCss: css for jquery-ui, defaults to jquery.ui.autocomplete.css
// * readlineCss: css for readline, defaults to jquery.readline.css
$.fn.readline = function(options) {
options = $.extend({
autocompleteCss: 'jquery.ui.autocomplete.css',
readlineCss: 'jquery.readline.css'
}, options);
input = $(this);
var prompt_id = this.selector + '_prompt';
$('head:first').append("").
append("");
input.
bind('keydown', 'ctrl+p', previous_line).
bind('keydown', 'up', previous_line).
bind('keydown', 'ctrl+n', next_line).
bind('keydown', 'down', next_line).
bind('keydown', 'ctrl+r', search_history).
bind('keydown', 'ctrl+g', exit_search_history).
bind('keydown', 'ctrl+u', clear_line).
autocomplete(original_autocomplete_options).
before('');
input_prompt = $(prompt_id);
if (startCompletion = options.startCompletion) {
input.bind('keydown', 'tab', tab_complete);
}
return this;
};
var addHistory = function(line) {
readline_history.push(line);
search_offset = readline_offset = 0;
};
var finishCompletion = function(completions) {
var onclose = function() {
input.autocomplete('option', original_autocomplete_options);
$('ul.ui-autocomplete').hide();
};
if (completions.length == 1) {
input.val(completions[0]);
onclose();
} else {
input.autocomplete('option', { close: onclose, source: completions.sort() }).
autocomplete('search');
}
};
$.readline = {
version: '0.1.0',
addHistory: addHistory,
finishCompletion: finishCompletion
};
})(jQuery);