Better override of Ace autocomplete token resolution to avoid flickering in the case no autocomplete options are available.

This commit is contained in:
Boaz Leskes 2014-02-09 22:48:00 +01:00
parent fc514d5371
commit 17a5a5eb0b
3 changed files with 71 additions and 44 deletions

View file

@ -6,7 +6,8 @@ define([
'jquery',
'utils',
'_',
'jquery-ui'
'jquery-ui',
'ace_ext_language_tools'
], function (history, kb, mappings, ace, $, utils, _) {
'use strict';
@ -1256,20 +1257,6 @@ define([
function getCompletions(aceEditor, session, pos, prefix, callback) {
// this is hacky, but there is at the moment no settings/way to do it differently
aceEditor.completer.autoInsert = false;
var token = aceEditor.getSession().getTokenAt(pos.row, pos.column);
var updatePrefix = false;
if (!editor.parser.isEmptyToken(token) && !isSeparatorToken(token)) {
// Ace doesn't care about tokenization when calculating prefix. It will thus stop on . in keys names.
if (token.value.indexOf('"') == 0) {
aceEditor.completer.base.column = token.start + 1;
}
else {
aceEditor.completer.base.column = token.start;
}
updatePrefix = true;
}
var context = getAutoCompleteContext(aceEditor, session, pos);
@ -1315,13 +1302,6 @@ define([
return 1;
});
if (updatePrefix && terms && terms.length) {
// we have to trigger a render update to make the new prefix take affect.
setTimeout(function () {
aceEditor.completer.changeListener();
}, 50);
}
callback(null, _.map(terms, function (t, i) {
t.insert_value = t.value;
t.value = '' + t.value; // normalize to strings
@ -1333,11 +1313,74 @@ define([
addChangeListener();
// Hook into Ace
// disable standard context based autocompletion.
ace.define('ace/autocomplete/text_completer', ['require', 'exports', 'module'], function (require, exports, module) {
exports.getCompletions = function (editor, session, pos, prefix, callback) {
callback(null, []);
}
});
var langTools = ace.require('ace/ext/language_tools'),
aceUtils = ace.require('ace/autocomplete/util'),
aceAutoComplete = ace.require('ace/autocomplete');
langTools.addCompleter({
getCompletions: getCompletions
});
editor.setOptions({
enableBasicAutocompletion: true
});
// Ace doesn't care about tokenization when calculating prefix. It will thus stop on . in keys names.
// we patch this behavior.
// CHECK ON ACE UPDATE
var aceAutoCompleteInstance = new aceAutoComplete.Autocomplete();
aceAutoCompleteInstance.autoInsert = false;
aceAutoCompleteInstance.gatherCompletions = function (ace_editor, callback) {
var session = ace_editor.getSession();
var pos = ace_editor.getCursorPosition();
var prefix;
// change starts here
var token = session.getTokenAt(pos.row, pos.column);
this.base = _.clone(pos);
if (!editor.parser.isEmptyToken(token) && !isSeparatorToken(token)) {
if (token.value.indexOf('"') == 0) {
prefix = token.value.substr(1);
this.base.column = token.start + 1;
}
else {
prefix = token.value;
this.base.column = token.start;
}
}
var matches = [];
aceUtils.parForEach(ace_editor.completers, function (completer, next) {
completer.getCompletions(ace_editor, session, pos, prefix, function (err, results) {
if (!err) {
matches = matches.concat(results);
}
next();
});
}, function () {
callback(null, {
prefix: prefix,
matches: matches
});
});
return true;
};
editor.__ace.completer = aceAutoCompleteInstance;
return {
completer: {
getCompletions: getCompletions
},
_test: {
getCompletions: getCompletions,
addReplacementInfoToContext: addReplacementInfoToContext,
addChangeListener: addChangeListener,
removeChangeListener: removeChangeListener

View file

@ -9,32 +9,16 @@ define([
'require',
'utils',
'zeroclip',
'ace_ext_language_tools',
'ace_ext_searchbox'
], function (ace, Autocomplete, $, mappings, output, SenseEditor, settings, require, utils, ZeroClipboard) {
'use strict';
// disable standard context based autocompletion.
ace.define('ace/autocomplete/text_completer', ['require', 'exports', 'module'], function(require, exports, module) {
exports.getCompletions = function(editor, session, pos, prefix, callback) {
callback(null, []);
}
});
ace.require('ace/ext/language_tools');
var input = new SenseEditor($('#editor'));
input.setOptions({
enableBasicAutocompletion: true
});
input.autocomplete = new Autocomplete(input);
input.$actions = $("#editor_actions");
ace.require('ace/ext/language_tools').addCompleter(input.autocomplete.completer);
input.commands.addCommand({
name: 'auto indent request',
bindKey: {win: 'Ctrl-I', mac: 'Command-I'},
@ -84,7 +68,7 @@ define([
});
zc.on('load', function () {
function setupCopyButton (cb) {
function setupCopyButton(cb) {
cb = typeof cb === 'function' ? cb : $.noop;
$copyAsCURL.css('visibility', 'hidden');
input.getCurrentRequestAsCURL(function (curl) {

View file

@ -58,8 +58,8 @@ define([
base: {},
changeListener : function () {}
}; // mimic auto complete
input.autocomplete.completer.getCompletions(input, input.getSession(), test.cursor, "",
function (err, terms) {
input.autocomplete._test.getCompletions(input, input.getSession(), test.cursor, "",
function (err, terms) {
if (test.no_context) {
ok(!terms || terms.length === 0, "Expected no context bug got terms.");