Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Console] Fix bool filter autocompletions and refactor #60361

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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