Fixes asynchronous autocompleter prefix updating

Before it could happen (if an async autocompleter returned late) that
the prefix used in the autocomplete was out of date. This fixes that.
This commit is contained in:
Zef Hemel 2014-03-20 15:27:51 +01:00
commit 31a32f2659

View file

@ -47,7 +47,7 @@ var Autocomplete = function() {
this.changeListener = this.changeListener.bind(this); this.changeListener = this.changeListener.bind(this);
this.mousedownListener = this.mousedownListener.bind(this); this.mousedownListener = this.mousedownListener.bind(this);
this.mousewheelListener = this.mousewheelListener.bind(this); this.mousewheelListener = this.mousewheelListener.bind(this);
this.changeTimer = lang.delayedCall(function() { this.changeTimer = lang.delayedCall(function() {
this.updateCompletions(true); this.updateCompletions(true);
}.bind(this)) }.bind(this))
@ -74,10 +74,10 @@ var Autocomplete = function() {
this.popup.setFontSize(editor.getFontSize()); this.popup.setFontSize(editor.getFontSize());
var lineHeight = renderer.layerConfig.lineHeight; var lineHeight = renderer.layerConfig.lineHeight;
var pos = renderer.$cursorLayer.getPixelPosition(this.base, true); var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
pos.left -= this.popup.getTextLeftOffset(); pos.left -= this.popup.getTextLeftOffset();
var rect = editor.container.getBoundingClientRect(); var rect = editor.container.getBoundingClientRect();
pos.top += rect.top - renderer.layerConfig.offset; pos.top += rect.top - renderer.layerConfig.offset;
pos.left += rect.left - editor.renderer.scrollLeft; pos.left += rect.left - editor.renderer.scrollLeft;
@ -94,7 +94,7 @@ var Autocomplete = function() {
this.editor.off("mousedown", this.mousedownListener); this.editor.off("mousedown", this.mousedownListener);
this.editor.off("mousewheel", this.mousewheelListener); this.editor.off("mousewheel", this.mousewheelListener);
this.changeTimer.cancel(); this.changeTimer.cancel();
if (this.popup) if (this.popup)
this.popup.hide(); this.popup.hide();
@ -182,10 +182,10 @@ var Autocomplete = function() {
this.gatherCompletions = function(editor, callback) { this.gatherCompletions = function(editor, callback) {
var session = editor.getSession(); var session = editor.getSession();
var pos = editor.getCursorPosition(); var pos = editor.getCursorPosition();
var line = session.getLine(pos.row); var line = session.getLine(pos.row);
var prefix = util.retrievePrecedingIdentifier(line, pos.column); var prefix = util.retrievePrecedingIdentifier(line, pos.column);
this.base = editor.getCursorPosition(); this.base = editor.getCursorPosition();
this.base.column -= prefix.length; this.base.column -= prefix.length;
@ -197,8 +197,11 @@ var Autocomplete = function() {
next(); next();
}); });
}, function() { }, function() {
// Fetch prefix again, because they may have changed by now
var pos = editor.getCursorPosition();
var line = session.getLine(pos.row);
callback(null, { callback(null, {
prefix: prefix, prefix: util.retrievePrecedingIdentifier(line, pos.column),
matches: matches matches: matches
}); });
}); });
@ -208,7 +211,7 @@ var Autocomplete = function() {
this.showPopup = function(editor) { this.showPopup = function(editor) {
if (this.editor) if (this.editor)
this.detach(); this.detach();
this.activated = true; this.activated = true;
this.editor = editor; this.editor = editor;
@ -223,10 +226,10 @@ var Autocomplete = function() {
editor.on("blur", this.blurListener); editor.on("blur", this.blurListener);
editor.on("mousedown", this.mousedownListener); editor.on("mousedown", this.mousedownListener);
editor.on("mousewheel", this.mousewheelListener); editor.on("mousewheel", this.mousewheelListener);
this.updateCompletions(); this.updateCompletions();
}; };
this.updateCompletions = function(keepPopupPosition) { this.updateCompletions = function(keepPopupPosition) {
if (keepPopupPosition && this.base && this.completions) { if (keepPopupPosition && this.base && this.completions) {
var pos = this.editor.getCursorPosition(); var pos = this.editor.getCursorPosition();
@ -243,7 +246,7 @@ var Autocomplete = function() {
var matches = results && results.matches; var matches = results && results.matches;
if (!matches || !matches.length) if (!matches || !matches.length)
return this.detach(); return this.detach();
// TODO reenable this when we have proper change tracking // TODO reenable this when we have proper change tracking
// if (matches.length == 1) // if (matches.length == 1)
// return this.insertMatch(matches[0]); // return this.insertMatch(matches[0]);
@ -299,16 +302,16 @@ var FilteredList = function(array, filterText, mutateData) {
matches = matches.sort(function(a, b) { matches = matches.sort(function(a, b) {
return b.exactMatch - a.exactMatch || b.score - a.score; return b.exactMatch - a.exactMatch || b.score - a.score;
}); });
// make unique // make unique
var prev = null; var prev = null;
matches = matches.filter(function(item){ matches = matches.filter(function(item){
var caption = item.value || item.caption || item.snippet; var caption = item.value || item.caption || item.snippet;
if (caption === prev) return false; if (caption === prev) return false;
prev = caption; prev = caption;
return true; return true;
}); });
this.filtered = matches; this.filtered = matches;
}; };
this.filterCompletions = function(items, needle) { this.filterCompletions = function(items, needle) {