Improve autocomplete support for async completers

This commit is contained in:
Samy Pessé 2014-01-31 22:19:32 +01:00 committed by Aaron O'Mullan
commit 09b9348852

View file

@ -60,6 +60,7 @@ var Autocomplete = function() {
this.insertMatch();
e.stop();
}.bind(this));
this.gatherCompletionsId = 0;
};
this.openPopup = function(editor, prefix, keepPopupPosition) {
@ -146,6 +147,8 @@ var Autocomplete = function() {
data = this.popup.getData(this.popup.getRow());
if (!data)
return false;
this.gatherCompletionsId = this.gatherCompletionsId + 1;
if (data.completer && data.completer.insertMatch) {
data.completer.insertMatch(this.editor);
} else {
@ -191,16 +194,14 @@ var Autocomplete = function() {
this.base.column -= prefix.length;
var matches = [];
util.parForEach(editor.completers, function(completer, next) {
editor.completers.forEach(function(completer) {
completer.getCompletions(editor, session, pos, prefix, function(err, results) {
if (!err)
matches = matches.concat(results);
next();
});
}, function() {
callback(null, {
prefix: prefix,
matches: matches
callback(null, {
prefix: prefix,
matches: matches
});
});
});
return true;
@ -229,6 +230,7 @@ var Autocomplete = function() {
};
this.updateCompletions = function(keepPopupPosition) {
var that = this;
if (keepPopupPosition && this.base && this.completions) {
var pos = this.editor.getCursorPosition();
var prefix = this.editor.session.getTextRange({start: this.base, end: pos});
@ -240,22 +242,39 @@ var Autocomplete = function() {
this.openPopup(this.editor, prefix, keepPopupPosition);
return;
}
// Save current gatherCompletions session, session is close when a match is insert
var _id = this.gatherCompletionsId;
this.gatherCompletions(this.editor, function(err, results) {
// Calcul prefix
var session = that.editor.getSession();
var pos = that.editor.getCursorPosition();
var line = session.getLine(pos.row);
var prefix = util.retrievePrecedingIdentifier(line, pos.column);
// Results matches
var matches = results && results.matches;
if (!matches || !matches.length)
return this.detach();
// TODO reenable this when we have proper change tracking
// if (matches.length == 1)
// return this.insertMatch(matches[0]);
// No prefix or no results -> close
if (!prefix || !prefix.length || !matches || !matches.length)
return this.detach();
// Wrong prefx or wrong session -> ignore
if (prefix.indexOf(results.prefix) != 0
|| _id != this.gatherCompletionsId)
return;
this.completions = new FilteredList(matches);
this.completions.setFilter(results.prefix);
this.completions.setFilter(prefix);
var filtered = this.completions.filtered;
if (!filtered.length)
return this.detach();
if (this.autoInsert && filtered.length == 1)
return this.insertMatch(filtered[0]);
this.openPopup(this.editor, results.prefix, keepPopupPosition);
this.openPopup(this.editor, prefix, keepPopupPosition);
}.bind(this));
};