Skip to content

Commit

Permalink
[Console] Fix bool filter autocompletions and refactor (#60361)
Browse files Browse the repository at this point in the history
The autocomplete lib component was controlling state that belongs to the legacy editor model and so it was moved there. The fix for filter autocompletion inside of "bool" was just adding "[" around the filter scoped entry.
* Remove reference to model code from autocomplete lib
* Also renamed the __tests__ dir to __jest__ to avoid re-running in mocha.
  • Loading branch information
jloleysens authored Mar 17, 2020
1 parent bc16fcd commit 0d23c51
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@
*/

import ace from 'brace';
import { Editor as IAceEditor } from 'brace';
import { Editor as IAceEditor, IEditSession as IAceEditSession } from 'brace';
import $ from 'jquery';
import { CoreEditor, Position, Range, Token, TokensProvider, EditorEvent } from '../../../types';
import {
CoreEditor,
Position,
Range,
Token,
TokensProvider,
EditorEvent,
AutoCompleterFunction,
} from '../../../types';
import { AceTokensProvider } from '../../../lib/ace_token_provider';
import * as curl from '../sense_editor/curl';
import smartResize from './smart_resize';
Expand Down Expand Up @@ -354,4 +362,48 @@ export class LegacyCoreEditor implements CoreEditor {
}
}
}

registerAutocompleter(getCompletions: AutoCompleterFunction): void {
// Hook into Ace

// disable standard context based autocompletion.
// @ts-ignore
ace.define('ace/autocomplete/text_completer', ['require', 'exports', 'module'], function(
require: any,
exports: any
) {
exports.getCompletions = function(
innerEditor: any,
session: any,
pos: any,
prefix: any,
callback: any
) {
callback(null, []);
};
});

const langTools = ace.acequire('ace/ext/language_tools');

langTools.setCompleters([
{
identifierRegexps: [
/[a-zA-Z_0-9\.\$\-\u00A2-\uFFFF]/, // adds support for dot character
],
getCompletions: (
DO_NOT_USE_1: IAceEditor,
DO_NOT_USE_2: IAceEditSession,
pos: { row: number; column: number },
prefix: string,
callback: (...args: any[]) => void
) => {
const position: Position = {
lineNumber: pos.row + 1,
column: pos.column + 1,
};
getCompletions(position, prefix, callback);
},
},
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,93 +84,90 @@ describe('Integration', () => {
changeListener: function() {},
}; // mimic auto complete

senseEditor.autocomplete._test.getCompletions(
senseEditor,
null,
{ row: cursor.lineNumber - 1, column: cursor.column - 1 },
'',
function(err, terms) {
if (testToRun.assertThrows) {
done();
return;
}
senseEditor.autocomplete._test.getCompletions(senseEditor, null, cursor, '', function(
err,
terms
) {
if (testToRun.assertThrows) {
done();
return;
}

if (err) {
throw err;
}
if (err) {
throw err;
}

if (testToRun.no_context) {
expect(!terms || terms.length === 0).toBeTruthy();
} else {
expect(terms).not.toBeNull();
expect(terms.length).toBeGreaterThan(0);
}
if (testToRun.no_context) {
expect(!terms || terms.length === 0).toBeTruthy();
} else {
expect(terms).not.toBeNull();
expect(terms.length).toBeGreaterThan(0);
}

if (!terms || terms.length === 0) {
done();
return;
}
if (!terms || terms.length === 0) {
done();
return;
}

if (testToRun.autoCompleteSet) {
const expectedTerms = _.map(testToRun.autoCompleteSet, function(t) {
if (typeof t !== 'object') {
t = { name: t };
}
return t;
});
if (terms.length !== expectedTerms.length) {
expect(_.pluck(terms, 'name')).toEqual(_.pluck(expectedTerms, 'name'));
} else {
const filteredActualTerms = _.map(terms, function(actualTerm, i) {
const expectedTerm = expectedTerms[i];
const filteredTerm = {};
_.each(expectedTerm, function(v, p) {
filteredTerm[p] = actualTerm[p];
});
return filteredTerm;
});
expect(filteredActualTerms).toEqual(expectedTerms);
if (testToRun.autoCompleteSet) {
const expectedTerms = _.map(testToRun.autoCompleteSet, function(t) {
if (typeof t !== 'object') {
t = { name: t };
}
return t;
});
if (terms.length !== expectedTerms.length) {
expect(_.pluck(terms, 'name')).toEqual(_.pluck(expectedTerms, 'name'));
} else {
const filteredActualTerms = _.map(terms, function(actualTerm, i) {
const expectedTerm = expectedTerms[i];
const filteredTerm = {};
_.each(expectedTerm, function(v, p) {
filteredTerm[p] = actualTerm[p];
});
return filteredTerm;
});
expect(filteredActualTerms).toEqual(expectedTerms);
}
}

const context = terms[0].context;
const {
cursor: { lineNumber, column },
} = testToRun;
senseEditor.autocomplete._test.addReplacementInfoToContext(
context,
{ lineNumber, column },
terms[0].value
);
const context = terms[0].context;
const {
cursor: { lineNumber, column },
} = testToRun;
senseEditor.autocomplete._test.addReplacementInfoToContext(
context,
{ lineNumber, column },
terms[0].value
);

function ac(prop, propTest) {
if (typeof testToRun[prop] !== 'undefined') {
if (propTest) {
propTest(context[prop], testToRun[prop], prop);
} else {
expect(context[prop]).toEqual(testToRun[prop]);
}
function ac(prop, propTest) {
if (typeof testToRun[prop] !== 'undefined') {
if (propTest) {
propTest(context[prop], testToRun[prop], prop);
} else {
expect(context[prop]).toEqual(testToRun[prop]);
}
}
}

function posCompare(actual, expected) {
expect(actual.lineNumber).toEqual(expected.lineNumber + lineOffset);
expect(actual.column).toEqual(expected.column);
}

function rangeCompare(actual, expected, name) {
posCompare(actual.start, expected.start, name + '.start');
posCompare(actual.end, expected.end, name + '.end');
}
function posCompare(actual, expected) {
expect(actual.lineNumber).toEqual(expected.lineNumber + lineOffset);
expect(actual.column).toEqual(expected.column);
}

ac('prefixToAdd');
ac('suffixToAdd');
ac('addTemplate');
ac('textBoxPosition', posCompare);
ac('rangeToReplace', rangeCompare);
done();
function rangeCompare(actual, expected, name) {
posCompare(actual.start, expected.start, name + '.start');
posCompare(actual.end, expected.end, name + '.end');
}
);

ac('prefixToAdd');
ac('suffixToAdd');
ac('addTemplate');
ac('textBoxPosition', posCompare);
ac('rangeToReplace', rangeCompare);
done();
});
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export class SenseEditor {
coreEditor,
parser: this.parser,
});
this.coreEditor.registerAutocompleter(this.autocomplete.getCompletions);
this.coreEditor.on(
'tokenizerUpdate',
this.highlightCurrentRequestsAndUpdateActionBar.bind(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
import '../../../application/models/sense_editor/sense_editor.test.mocks';

const _ = require('lodash');
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
import '../../../application/models/sense_editor/sense_editor.test.mocks';
import 'brace';
import 'brace/mode/javascript';
import 'brace/mode/json';
const _ = require('lodash');
import { UrlParams } from '../../autocomplete/url_params';
import { populateContext } from '../../autocomplete/engine';
Expand Down
71 changes: 17 additions & 54 deletions src/plugins/console/public/lib/autocomplete/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*/

import _ from 'lodash';
import ace, { Editor as AceEditor, IEditSession } from 'brace';
import { i18n } from '@kbn/i18n';

// TODO: All of these imports need to be moved to the core editor so that it can inject components from there.
import {
getTopLevelUrlCompleteComponents,
getEndpointBodyCompleteComponents,
Expand All @@ -39,7 +39,7 @@ import { createTokenIterator } from '../../application/factories';

import { Position, Token, Range, CoreEditor } from '../../types';

let LAST_EVALUATED_TOKEN: any = null;
let lastEvaluatedToken: any = null;

function isUrlParamsToken(token: any) {
switch ((token || {}).type) {
Expand Down Expand Up @@ -889,7 +889,7 @@ export default function({ coreEditor: editor, parser }: { coreEditor: CoreEditor

if (!currentToken) {
if (pos.lineNumber === 1) {
LAST_EVALUATED_TOKEN = null;
lastEvaluatedToken = null;
return;
}
currentToken = { position: { column: 0, lineNumber: 0 }, value: '', type: '' }; // empty row
Expand All @@ -902,26 +902,26 @@ export default function({ coreEditor: editor, parser }: { coreEditor: CoreEditor
if (parser.isEmptyToken(nextToken)) {
// Empty line, or we're not on the edge of current token. Save the current position as base
currentToken.position.column = pos.column;
LAST_EVALUATED_TOKEN = currentToken;
lastEvaluatedToken = currentToken;
} else {
nextToken.position.lineNumber = pos.lineNumber;
LAST_EVALUATED_TOKEN = nextToken;
lastEvaluatedToken = nextToken;
}
return;
}

if (!LAST_EVALUATED_TOKEN) {
LAST_EVALUATED_TOKEN = currentToken;
if (!lastEvaluatedToken) {
lastEvaluatedToken = currentToken;
return; // wait for the next typing.
}

if (
LAST_EVALUATED_TOKEN.position.column !== currentToken.position.column ||
LAST_EVALUATED_TOKEN.position.lineNumber !== currentToken.position.lineNumber ||
LAST_EVALUATED_TOKEN.value === currentToken.value
lastEvaluatedToken.position.column !== currentToken.position.column ||
lastEvaluatedToken.position.lineNumber !== currentToken.position.lineNumber ||
lastEvaluatedToken.value === currentToken.value
) {
// not on the same place or nothing changed, cache and wait for the next time
LAST_EVALUATED_TOKEN = currentToken;
lastEvaluatedToken = currentToken;
return;
}

Expand All @@ -935,7 +935,7 @@ export default function({ coreEditor: editor, parser }: { coreEditor: CoreEditor
return;
}

LAST_EVALUATED_TOKEN = currentToken;
lastEvaluatedToken = currentToken;
editor.execCommand('startAutocomplete');
},
100);
Expand All @@ -947,17 +947,7 @@ export default function({ coreEditor: editor, parser }: { coreEditor: CoreEditor
}
}

function getCompletions(
DO_NOT_USE: AceEditor,
DO_NOT_USE_SESSION: IEditSession,
pos: { row: number; column: number },
prefix: string,
callback: (...args: any[]) => void
) {
const position: Position = {
lineNumber: pos.row + 1,
column: pos.column + 1,
};
function getCompletions(position: Position, prefix: string, callback: (...args: any[]) => void) {
try {
const context = getAutoCompleteContext(editor, position);
if (!context) {
Expand Down Expand Up @@ -1028,39 +1018,12 @@ export default function({ coreEditor: editor, parser }: { coreEditor: CoreEditor

editor.on('changeSelection', editorChangeListener);

// Hook into Ace

// disable standard context based autocompletion.
// @ts-ignore
ace.define('ace/autocomplete/text_completer', ['require', 'exports', 'module'], function(
require: any,
exports: any
) {
exports.getCompletions = function(
innerEditor: any,
session: any,
pos: any,
prefix: any,
callback: any
) {
callback(null, []);
};
});

const langTools = ace.acequire('ace/ext/language_tools');

langTools.setCompleters([
{
identifierRegexps: [
/[a-zA-Z_0-9\.\$\-\u00A2-\uFFFF]/, // adds support for dot character
],
getCompletions,
},
]);

return {
getCompletions,
// TODO: This needs to be cleaned up
_test: {
getCompletions,
getCompletions: (_editor: any, _editSession: any, pos: any, prefix: any, callback: any) =>
getCompletions(pos, prefix, callback),
addReplacementInfoToContext,
addChangeListener: () => editor.on('changeSelection', editorChangeListener),
removeChangeListener: () => editor.off('changeSelection', editorChangeListener),
Expand Down
Loading

0 comments on commit 0d23c51

Please sign in to comment.