mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Console/fix folding with script (#216817)
Fixes https://github.com/elastic/kibana/issues/212902 ## Summary This PR fixes the logic for finding folding ranges by ignoring opening/closing markers inside triple-quote strings. **How to test:** Verify that the `script` field in the following request is folded correctly: ``` 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 "SCRIPT": parts = field.splitOnToken('.'); } } """, "params": { "fields": [ "user.name", "geo.city", "does.not.exist", "this.is.quite.a.deep.field" ] } } } ] } } ``` Note: The logic is for finding the ranges is best-effort without compromising performance. We currently iterate through each line in the text and use regex, but there are some cases which are not covered by this logic; for example, opening parenthesis, followed by a string in the same line would not be foldable. In order to cover all cases correctly, we would need to iterate through every single character, but that would make the logic much more complex and might affect performance if we have a lot of text in the editor, as these folding ranges are computed on every change in the editor.
This commit is contained in:
parent
f402033eab
commit
d9477a74d4
2 changed files with 32 additions and 17 deletions
|
@ -14,25 +14,29 @@ describe('getFoldingRanges', () => {
|
|||
// 1 PUT /test/_doc/1
|
||||
// 2 {
|
||||
// 3 "some_key": {
|
||||
// 4 "some_inner_key": """{
|
||||
// 5 "multi_line": "json string"
|
||||
// 6 }""",
|
||||
// 7 "some_other_key": 123
|
||||
// 8 },
|
||||
// 9 "outer_key_2": [
|
||||
// 10 1,
|
||||
// 11 2,
|
||||
// 12 3
|
||||
// 13 ]
|
||||
// 14 }
|
||||
// 4 "some_inner_key": """
|
||||
// 5 "multi_line_json": { // Should ignore this parenthesis
|
||||
// 6 "foo": "bar"
|
||||
// 7 } // Should ignore this parenthesis
|
||||
// 8 """,
|
||||
// 9 "some_other_key": 123
|
||||
// 10 },
|
||||
// 11 "outer_key_2": [
|
||||
// 12 1,
|
||||
// 13 2,
|
||||
// 14 3
|
||||
// 15 ]
|
||||
// 16 }
|
||||
|
||||
const SAMPLE_INPUT = [
|
||||
'PUT /test/_doc/1',
|
||||
'{ ',
|
||||
' "some_key": { ',
|
||||
' "some_inner_key": """{',
|
||||
' "multi_line": "json string"',
|
||||
' }""",',
|
||||
' "some_inner_key": """',
|
||||
' "multi_line_json": {',
|
||||
' "foo": "bar',
|
||||
' }',
|
||||
' """,',
|
||||
' "some_other_key": 123',
|
||||
' },',
|
||||
' "outer_key_2": [',
|
||||
|
@ -45,14 +49,14 @@ describe('getFoldingRanges', () => {
|
|||
|
||||
it('returns correct ranges for parentheses', () => {
|
||||
const expectedRanges = [
|
||||
{ start: 3, end: 7 },
|
||||
{ start: 2, end: 13 },
|
||||
{ start: 3, end: 9 },
|
||||
{ start: 2, end: 15 },
|
||||
];
|
||||
expect(getFoldingRanges(SAMPLE_INPUT, '{', '}')).toEqual(expectedRanges);
|
||||
});
|
||||
|
||||
it('returns correct ranges for square brackets', () => {
|
||||
const expectedRanges = [{ start: 9, end: 12 }];
|
||||
const expectedRanges = [{ start: 11, end: 14 }];
|
||||
expect(getFoldingRanges(SAMPLE_INPUT, '[', ']')).toEqual(expectedRanges);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,14 +23,25 @@ const getClosingLineRegex = (closingMarker: string) => {
|
|||
return new RegExp(regExStr);
|
||||
};
|
||||
|
||||
// A regex that matches a line containing a complete triple-quote string
|
||||
const inlineTripleQuoteString = /^.*?"""(.*?)""".*$/m;
|
||||
|
||||
export const getFoldingRanges = (lines: string[], openingMarker: string, closingMarker: string) => {
|
||||
const ranges: monaco.languages.ProviderResult<monaco.languages.FoldingRange[]> = [];
|
||||
const stack: number[] = [];
|
||||
const openingLineRegex = getOpeningLineRegex(openingMarker);
|
||||
const closingLineRegex = getClosingLineRegex(closingMarker);
|
||||
let insideTripleQuotes = false;
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const lineContent = lines[i].trim();
|
||||
if (lineContent.includes('"""') && !inlineTripleQuoteString.test(lineContent)) {
|
||||
insideTripleQuotes = !insideTripleQuotes;
|
||||
}
|
||||
if (insideTripleQuotes) {
|
||||
// If we are inside a multi-line triple-quote string, ignore opening/closing markers
|
||||
continue;
|
||||
}
|
||||
if (openingLineRegex.test(lineContent)) {
|
||||
stack.push(i + 1); // Line numbers start from 1 so we need to add 1 to the current index
|
||||
} else if (closingLineRegex.test(lineContent)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue