mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Console] Disable autocomplete suggestions inside scripts (#216986)
Fixes https://github.com/elastic/kibana/issues/212904 ## Summary This PR disables autocomplete suggestions if the curser is inside scripts (triple-quote strings). **How to test:** Verify that there are no autocomplete suggestions when you place the cursor inside the script in the request below: ``` POST _ingest/pipeline/_simulate { "pipeline": { "processors": [ { "script": { "source": """ for (field in params['fields']){ if (!$(field, '').isEmpty()){ def value = $(field, ''); def hash = value.sha256(); // Now we need to traverse as deep as needed // and write to that field // because we do not have a simple // set operation available parts = field.splitOnToken('.'); } } """, "params": { "fields": [ "user.name", "geo.city", "does.not.exist", "this.is.quite.a.deep.field" ] } } } ] } } ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
f833e09121
commit
b5a30054c7
4 changed files with 88 additions and 9 deletions
|
@ -38,6 +38,7 @@ import {
|
|||
shouldTriggerSuggestions,
|
||||
trackSentRequests,
|
||||
getRequestFromEditor,
|
||||
isInsideTripleQuotes,
|
||||
} from './utils';
|
||||
|
||||
import type { AdjustedParsedRequest } from './types';
|
||||
|
@ -783,22 +784,61 @@ export class MonacoEditorActionsProvider {
|
|||
return this.editor.getPosition() ?? { lineNumber: 1, column: 1 };
|
||||
}
|
||||
|
||||
private async isPositionInsideScript(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: monaco.Position
|
||||
): Promise<boolean> {
|
||||
const selectedRequests = await this.getSelectedParsedRequests();
|
||||
|
||||
for (const request of selectedRequests) {
|
||||
if (
|
||||
request.startLineNumber <= position.lineNumber &&
|
||||
request.endLineNumber >= position.lineNumber
|
||||
) {
|
||||
const requestContentBefore = model.getValueInRange({
|
||||
startLineNumber: request.startLineNumber,
|
||||
startColumn: 1,
|
||||
endLineNumber: position.lineNumber,
|
||||
endColumn: position.column,
|
||||
});
|
||||
|
||||
if (isInsideTripleQuotes(requestContentBefore)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (request.startLineNumber > position.lineNumber) {
|
||||
// Stop iteration once we pass the cursor position
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return false if no match
|
||||
return false;
|
||||
}
|
||||
|
||||
private triggerSuggestions() {
|
||||
const model = this.editor.getModel();
|
||||
const position = this.editor.getPosition();
|
||||
if (!model || !position) {
|
||||
return;
|
||||
}
|
||||
const lineContentBefore = model.getValueInRange({
|
||||
startLineNumber: position.lineNumber,
|
||||
startColumn: 1,
|
||||
endLineNumber: position.lineNumber,
|
||||
endColumn: position.column,
|
||||
this.isPositionInsideScript(model, position).then((isCursorInsideScript) => {
|
||||
if (isCursorInsideScript) {
|
||||
// Don't trigger autocomplete suggestions inside scripts
|
||||
return;
|
||||
}
|
||||
|
||||
const lineContentBefore = model.getValueInRange({
|
||||
startLineNumber: position.lineNumber,
|
||||
startColumn: 1,
|
||||
endLineNumber: position.lineNumber,
|
||||
endColumn: position.column,
|
||||
});
|
||||
// if the line is empty or it matches specified regex, trigger suggestions
|
||||
if (!lineContentBefore.trim() || shouldTriggerSuggestions(lineContentBefore)) {
|
||||
this.editor.trigger(TRIGGER_SUGGESTIONS_ACTION_LABEL, TRIGGER_SUGGESTIONS_HANDLER_ID, {});
|
||||
}
|
||||
});
|
||||
// if the line is empty or it matches specified regex, trigger suggestions
|
||||
if (!lineContentBefore.trim() || shouldTriggerSuggestions(lineContentBefore)) {
|
||||
this.editor.trigger(TRIGGER_SUGGESTIONS_ACTION_LABEL, TRIGGER_SUGGESTIONS_HANDLER_ID, {});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
getUrlPathCompletionItems,
|
||||
shouldTriggerSuggestions,
|
||||
getInsertText,
|
||||
isInsideTripleQuotes,
|
||||
} from './autocomplete_utils';
|
||||
|
||||
describe('autocomplete_utils', () => {
|
||||
|
@ -292,4 +293,25 @@ describe('autocomplete_utils', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isInsideTripleQuotes', () => {
|
||||
it('should return false for an empty string', () => {
|
||||
expect(isInsideTripleQuotes('')).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for a request without triple quotes', () => {
|
||||
const request = `POST _search\n{\n \"query\": {\n \"match\": {\n \"message\": \"hello world\"\n }\n }\n}`;
|
||||
expect(isInsideTripleQuotes(request)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true for a request ending inside triple quotes', () => {
|
||||
const request = `POST _ingest/pipeline/_simulate\n{\n \"pipeline\": {\n \"processors\": [\n {\n \"script\": {\n \"source\":\n \"\"\"\n for (field in params['fields']){\n if (!$(field, '').isEmpty()){\n`;
|
||||
expect(isInsideTripleQuotes(request)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for a properly closed triple-quoted string', () => {
|
||||
const request = `POST _ingest/pipeline/_simulate\n{\n \"pipeline\": {\n \"processors\": [\n {\n \"script\": {\n \"source\":\n \"\"\"\n return 'hello';\n \"\"\"\n }\n }\n ]\n }\n}`;
|
||||
expect(isInsideTripleQuotes(request)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -470,3 +470,19 @@ export const hasUnclosedQuote = (lineContent: string): boolean => {
|
|||
|
||||
return insideString;
|
||||
};
|
||||
|
||||
export const isInsideTripleQuotes = (text: string) => {
|
||||
let insideTripleQuote = false;
|
||||
let i = 0;
|
||||
|
||||
while (i < text.length) {
|
||||
if (text.startsWith('"""', i)) {
|
||||
insideTripleQuote = !insideTripleQuote;
|
||||
i += 3; // Skip the triple quotes
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return insideTripleQuote;
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@ export {
|
|||
getUrlParamsCompletionItems,
|
||||
getBodyCompletionItems,
|
||||
shouldTriggerSuggestions,
|
||||
isInsideTripleQuotes,
|
||||
} from './autocomplete_utils';
|
||||
export { getLineTokens, containsUrlParams } from './tokens_utils';
|
||||
export { getStatusCodeDecorations } from './status_code_decoration_utils';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue