mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Console] Add highlighting for painless language (#202695)
Closes https://github.com/elastic/kibana/issues/201672?reload=1?reload=1 ## Summary This PR adds existing painless rules to the console language so that the painless scripts are correctly highlighted. We are adding a painless starting rule that matches a string `"*_script"`, `"inline"`, or `"source"`, followed by a triple quote, in order to prevent clashing with the existing rules for triple-quote strings. Example request with a script: ``` POST _ingest/pipeline/_simulate { "pipeline": { "processors": [ { "script": { "description": "Extract 'tags' from 'env' field", "lang": "painless", "source": """ String[] envSplit = ctx['env'].splitOnToken(params['delimiter']); ArrayList tags = new ArrayList(); tags.add(envSplit[params['position']].trim()); ctx['tags'] = tags; """, "params": { "delimiter": "-", "position": 1 } } } ] }, "docs": [ { "_source": { "env": "es01-prod" } } ] } ``` <img width="1049" alt="Screenshot 2024-12-03 at 12 02 52" src="https://github.com/user-attachments/assets/fb249953-a998-40c0-9775-3474e15b5de2">
This commit is contained in:
parent
9997dabf90
commit
2fcd323927
2 changed files with 85 additions and 0 deletions
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { lexerRules as painlessLexerRules } from '../../painless/lexer_rules';
|
||||
|
||||
/*
|
||||
* This rule is used inside json root to start a painless highlighting sequence
|
||||
*/
|
||||
export const buildPainlessStartRule = (painlessRoot: string = 'painless_root') => {
|
||||
return [
|
||||
/("(?:[^"]*_)?script"|"inline"|"source")(\s*?)(:)(\s*?)(""")/,
|
||||
[
|
||||
'variable',
|
||||
'whitespace',
|
||||
'punctuation.colon',
|
||||
'whitespace',
|
||||
{
|
||||
token: 'punctuation',
|
||||
next: `@${painlessRoot}`,
|
||||
},
|
||||
],
|
||||
];
|
||||
};
|
||||
|
||||
/*
|
||||
* This function creates a group of rules needed for painless highlighting in console.
|
||||
* It reuses the lexer rules from the "painless" language, but since not all rules are referenced in the root
|
||||
* tokenizer and to avoid conflicts with existing console rules, only selected rules are used.
|
||||
*/
|
||||
export const buildPainlessRules = (painlessRoot: string = 'painless_root') => {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { root, comment, string_dq, string_sq } = painlessLexerRules.tokenizer;
|
||||
return {
|
||||
[painlessRoot]: [
|
||||
// the rule to end painless highlighting and get back to the previous tokenizer state
|
||||
[
|
||||
/"""/,
|
||||
{
|
||||
token: 'punctuation',
|
||||
next: '@pop',
|
||||
},
|
||||
],
|
||||
...root,
|
||||
],
|
||||
comment,
|
||||
string_dq,
|
||||
string_sq,
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* These language attributes need to be added to the console language definition for painless tokenizer
|
||||
* to work correctly.
|
||||
*/
|
||||
export const painlessLanguageAttributes = {
|
||||
keywords: painlessLexerRules.keywords,
|
||||
primitives: painlessLexerRules.primitives,
|
||||
constants: painlessLexerRules.constants,
|
||||
operators: painlessLexerRules.operators,
|
||||
symbols: painlessLexerRules.symbols,
|
||||
digits: painlessLexerRules.digits,
|
||||
octaldigits: painlessLexerRules.octaldigits,
|
||||
binarydigits: painlessLexerRules.binarydigits,
|
||||
hexdigits: painlessLexerRules.hexdigits,
|
||||
};
|
|
@ -8,6 +8,11 @@
|
|||
*/
|
||||
|
||||
import { buildSqlRules, buildSqlStartRule, sqlLanguageAttributes } from './nested_sql';
|
||||
import {
|
||||
buildPainlessRules,
|
||||
buildPainlessStartRule,
|
||||
painlessLanguageAttributes,
|
||||
} from './nested_painless';
|
||||
import { monaco } from '../../..';
|
||||
import { globals } from '../../common/lexer_rules';
|
||||
import { buildXjsonRules } from '../../xjson/lexer_rules/xjson';
|
||||
|
@ -16,11 +21,13 @@ export const consoleSharedLanguageConfiguration: monaco.languages.LanguageConfig
|
|||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')'],
|
||||
['"""', '"""\n'],
|
||||
],
|
||||
autoClosingPairs: [
|
||||
{ open: '{', close: '}' },
|
||||
{ open: '[', close: ']' },
|
||||
{ open: '(', close: ')' },
|
||||
{ open: '"', close: '"' },
|
||||
{ open: '"""', close: '"""' },
|
||||
],
|
||||
|
@ -100,10 +107,13 @@ xjsonRules.json_root = [
|
|||
matchToken('variable.template', /("\${\w+}")/),
|
||||
// @ts-expect-error include a rule to start sql highlighting
|
||||
buildSqlStartRule(),
|
||||
// @ts-expect-error include a rule to start painless highlighting
|
||||
buildPainlessStartRule(),
|
||||
...xjsonRules.json_root,
|
||||
];
|
||||
|
||||
const sqlRules = buildSqlRules();
|
||||
const painlessRules = buildPainlessRules();
|
||||
/*
|
||||
Lexer rules that are shared between the Console editor and the Console output panel.
|
||||
*/
|
||||
|
@ -111,6 +121,8 @@ export const consoleSharedLexerRules: monaco.languages.IMonarchLanguage = {
|
|||
...(globals as any),
|
||||
defaultToken: 'invalid',
|
||||
...sqlLanguageAttributes,
|
||||
...painlessLanguageAttributes,
|
||||
keywords: [...sqlLanguageAttributes.keywords, ...painlessLanguageAttributes.keywords],
|
||||
tokenizer: {
|
||||
root: [
|
||||
// warning comment
|
||||
|
@ -138,5 +150,7 @@ export const consoleSharedLexerRules: monaco.languages.IMonarchLanguage = {
|
|||
...xjsonRules,
|
||||
// include sql rules
|
||||
...sqlRules,
|
||||
// include painless rules
|
||||
...painlessRules,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue