diff --git a/lib/ace/autocomplete.js b/lib/ace/autocomplete.js index de30a740..34462894 100644 --- a/lib/ace/autocomplete.js +++ b/lib/ace/autocomplete.js @@ -54,13 +54,14 @@ var Autocomplete = function() { }; (function() { + this.gatherCompletionsId = 0; + this.$init = function() { this.popup = new AcePopup(document.body || document.documentElement); this.popup.on("click", function(e) { this.insertMatch(); e.stop(); }.bind(this)); - this.gatherCompletionsId = 0; }; this.openPopup = function(editor, prefix, keepPopupPosition) { @@ -96,6 +97,10 @@ var Autocomplete = function() { this.editor.off("mousedown", this.mousedownListener); this.editor.off("mousewheel", this.mousewheelListener); this.changeTimer.cancel(); + + if (this.popup && this.popup.isOpen) { + this.gatherCompletionsId = this.gatherCompletionsId + 1; + } if (this.popup) this.popup.hide(); @@ -147,7 +152,6 @@ 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); @@ -194,13 +198,15 @@ var Autocomplete = function() { this.base.column -= prefix.length; var matches = []; - editor.completers.forEach(function(completer) { + var total = editor.completers.length; + editor.completers.forEach(function(completer, i) { completer.getCompletions(editor, session, pos, prefix, function(err, results) { if (!err) matches = matches.concat(results); callback(null, { prefix: prefix, - matches: matches + matches: matches, + left: total - (i + 1) }); }); }); @@ -239,6 +245,10 @@ var Autocomplete = function() { this.completions.setFilter(prefix); if (!this.completions.filtered.length) return this.detach(); + if (this.completions.filtered.length == 1 + && this.completions.filtered[0].value == prefix + && !this.completions.filtered[0].snippet) + return this.detach(); this.openPopup(this.editor, prefix, keepPopupPosition); return; } @@ -246,6 +256,11 @@ var Autocomplete = function() { // Save current gatherCompletions session, session is close when a match is insert var _id = this.gatherCompletionsId; this.gatherCompletions(this.editor, function(err, results) { + var doDetach = function() { + if (results.left > 0) return; + return this.detach(); + }.bind(this); + // Calcul prefix var session = that.editor.getSession(); var pos = that.editor.getCursorPosition(); @@ -260,9 +275,9 @@ var Autocomplete = function() { // No prefix or no results -> close if (!prefix || !prefix.length || !matches || !matches.length) - return this.detach(); + return doDetach(); - // Wrong prefx or wrong session -> ignore + // Wrong prefix or wrong session -> ignore if (prefix.indexOf(results.prefix) != 0 || _id != this.gatherCompletionsId) return; @@ -270,10 +285,19 @@ var Autocomplete = function() { this.completions = new FilteredList(matches); this.completions.setFilter(prefix); var filtered = this.completions.filtered; + + // No results if (!filtered.length) - return this.detach(); + return doDetach(); + + // One result equals to the prefix + if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet) + return doDetach(); + + // Autoinsert if one result if (this.autoInsert && filtered.length == 1) return this.insertMatch(filtered[0]); + this.openPopup(this.editor, prefix, keepPopupPosition); }.bind(this)); }; diff --git a/lib/ace/ext/language_tools.js b/lib/ace/ext/language_tools.js index deb1973d..fa913e5b 100644 --- a/lib/ace/ext/language_tools.js +++ b/lib/ace/ext/language_tools.js @@ -147,10 +147,6 @@ var onChangeAutocomplete = function(e) { return; } - // Append added text to the line - line += text; - pos.column += text.length; - // The prefix to autocomplete for var prefix = util.retrievePrecedingIdentifier(line, pos.column); @@ -186,7 +182,7 @@ require("../config").defineOptions(Editor.prototype, "editor", { // On each change automatically trigger the autocomplete this.commands.on('afterExec', onChangeAutocomplete); } else { - this.removeListener('change', onChangeAutocomplete); + this.removeListener('afterExec', onChangeAutocomplete); this.commands.removeCommand(Autocomplete.startCommand); } },