diff --git a/ace.d.ts b/ace.d.ts index 3a1337028d1..fc8f81416a4 100644 --- a/ace.d.ts +++ b/ace.d.ts @@ -1008,6 +1008,7 @@ export namespace Ace { callback: CompleterCallback): void; getDocTooltip?(item: Completion): undefined | string | Completion; id?: string; + triggerCharacters?: string[] } export class AceInline { diff --git a/src/autocomplete/util.js b/src/autocomplete/util.js index 093c420095c..97228e94376 100644 --- a/src/autocomplete/util.js +++ b/src/autocomplete/util.js @@ -54,3 +54,15 @@ exports.getCompletionPrefix = function (editor) { }.bind(this)); return prefix || this.retrievePrecedingIdentifier(line, pos.column); }; + +exports.triggerAutocomplete = function (editor) { + var pos = editor.getCursorPosition(); + var line = editor.session.getLine(pos.row); + var column = (pos.column === 0) ? 0 : pos.column - 1; + var previousChar = line[column]; + return editor.completers.some((el) => { + if (el.triggerCharacters && Array.isArray(el.triggerCharacters)) { + return el.triggerCharacters.includes(previousChar); + } + }); +}; diff --git a/src/autocomplete_test.js b/src/autocomplete_test.js index 56815c9c8ad..da3d5d33cee 100644 --- a/src/autocomplete_test.js +++ b/src/autocomplete_test.js @@ -249,6 +249,45 @@ module.exports = { done(); }, 10); }, + "test: trigger autocomplete for specific characters": function (done) { + var editor = initEditor("document"); + + editor.completers = [ + { + getCompletions: function (editor, session, pos, prefix, callback) { + var completions = [ + { + caption: "append", + value: "append" + }, { + caption: "all", + value: "all" + } + ]; + callback(null, completions); + }, + triggerCharacters: ["."] + } + ]; + + editor.moveCursorTo(0, 8); + sendKey("."); + var popup = editor.completer.popup; + check(function () { + assert.equal(popup.data.length, 2); + editor.onCommandKey(null, 0, 13); + assert.equal(editor.getValue(), "document.all"); + done(); + }); + + function check(callback) { + popup = editor.completer.popup; + popup.renderer.on("afterRender", function wait() { + popup.renderer.off("afterRender", wait); + callback(); + }); + } + }, "test: empty message if no suggestions available": function(done) { var editor = initEditor(""); var emptyMessageText = "No suggestions."; diff --git a/src/ext/language_tools.js b/src/ext/language_tools.js index 44e39ffcf24..1e32fa77f0d 100644 --- a/src/ext/language_tools.js +++ b/src/ext/language_tools.js @@ -143,8 +143,9 @@ var doLiveAutocomplete = function(e) { } else if (e.command.name === "insertstring") { var prefix = util.getCompletionPrefix(editor); - // Only autocomplete if there's a prefix that can be matched - if (prefix && !hasCompleter) { + // Only autocomplete if there's a prefix that can be matched or previous char is trigger character + var triggerAutocomplete = util.triggerAutocomplete(editor); + if ((prefix || triggerAutocomplete) && !hasCompleter) { var completer = Autocomplete.for(editor); // Set a flag for auto shown completer.autoShown = true;