diff --git a/lib/ace/autocomplete.js b/lib/ace/autocomplete.js index 1e65fc6b..fef14ff4 100644 --- a/lib/ace/autocomplete.js +++ b/lib/ace/autocomplete.js @@ -35,6 +35,7 @@ var HashHandler = require("./keyboard/hash_handler").HashHandler; var AcePopup = require("./autocomplete/popup").AcePopup; var util = require("./autocomplete/util"); var event = require("./lib/event"); +var lang = require("./lib/lang"); var Autocomplete = function() { this.keyboardHandler = new HashHandler(); @@ -44,6 +45,10 @@ var Autocomplete = function() { this.changeListener = this.changeListener.bind(this); this.mousedownListener = this.mousedownListener.bind(this); this.mousewheelListener = this.mousewheelListener.bind(this); + + this.changeTimer = lang.delayedCall(function() { + this.updateCompletions(true); + }.bind(this)) }; (function() { @@ -55,22 +60,23 @@ var Autocomplete = function() { }.bind(this)); }; - this.openPopup = function(editor) { + this.openPopup = function(editor, keepPopupPosition) { if (!this.popup) this.$init(); this.popup.setData(this.completions.filtered); var renderer = editor.renderer; - var lineHeight = renderer.layerConfig.lineHeight; - var pos = renderer.$cursorLayer.getPixelPosition(null, true); - var rect = editor.container.getBoundingClientRect(); - pos.top += rect.top - renderer.layerConfig.offset; - pos.left += rect.left; - pos.left += renderer.$gutterLayer.gutterWidth; - - this.popup.show(pos, lineHeight); + if (!keepPopupPosition) { + var lineHeight = renderer.layerConfig.lineHeight; + var pos = renderer.$cursorLayer.getPixelPosition(null, true); + var rect = editor.container.getBoundingClientRect(); + pos.top += rect.top - renderer.layerConfig.offset; + pos.left += rect.left; + pos.left += renderer.$gutterLayer.gutterWidth; + this.popup.show(pos, lineHeight); + } renderer.updateText(); }; @@ -79,7 +85,8 @@ var Autocomplete = function() { this.editor.removeEventListener("changeSelection", this.changeListener); this.editor.removeEventListener("blur", this.changeListener); this.editor.removeEventListener("mousedown", this.changeListener); - + this.changeTimer.cancel(); + if (this.popup) this.popup.hide(); @@ -88,7 +95,7 @@ var Autocomplete = function() { this.changeListener = function(e) { if (this.activated) - this.showPopup(this.editor); + this.changeTimer.schedule(); else this.detach(); }; @@ -131,8 +138,8 @@ var Autocomplete = function() { } else { if (data.value) data = data.value; - if (data.prefix) - this.editor.removeWordLeft(); + if (this.completions.filterText) + this.editor.removeWordLeft(); this.editor.insert(data); } }; @@ -182,6 +189,8 @@ var Autocomplete = function() { this.showPopup = function(editor) { if (this.editor) this.detach(); + + this.activated = true; this.editor = editor; if (editor.completer != this) { @@ -194,17 +203,21 @@ var Autocomplete = function() { editor.on("changeSelection", this.changeListener); editor.on("blur", this.blurListener); editor.on("mousedown", this.mousedownListener); - + this.updateCompletions(); + } + + this.updateCompletions = function(keepPopupPosition) { this.gatherCompletions(this.editor, function(err, results) { var matches = results && results.matches; if (!matches || !matches.length) return this.detach(); - if (matches.length == 1) - return this.insertMatch(matches[0]); + // TODO reenable this when we have proper change tracking + // if (matches.length == 1) + // return this.insertMatch(matches[0]); this.completions = new FilteredList(matches); this.completions.setFilter(results.prefix); - this.openPopup(editor); + this.openPopup(this.editor, keepPopupPosition); this.popup.setHighlight(results.prefix); }.bind(this)); }; @@ -243,7 +256,7 @@ var FilteredList = function(array, mutateData) { }; (function(){ this.setFilter = function(str) { - + this.filterText = str; }; }).call(FilteredList.prototype);