Support for painless language autocomplete within monaco#80577
Support for painless language autocomplete within monaco#80577alisonelizabeth merged 40 commits intoelastic:masterfrom
Conversation
c452ced to
f02b836
Compare
7ad74a6 to
ed23ea1
Compare
|
Pinging @elastic/es-ui (Team:Elasticsearch UI) |
|
@jloleysens I believe I addressed your comments. What are your thoughts about moving ahead with the review/merge of this PR without the ES changes merged? Since the ES changes are only used in the script to generate the autocomplete definitions, it seems minimal risk. I will run the script again once the ES changes are merged to address any updates. I’d like to get this code in so testing can begin and it can be integrated in ingest node pipelines and the runtime fields editor. I went ahead and moved the PR out of draft. If you’re OK with this, would you mind taking another look and also test (if you haven’t yet)? Also, I want to point out that the autocomplete definitions adds ~9MB to the |
|
@elasticmachine merge upstream |
|
@elasticmachine merge upstream |
|
@elasticmachine merge upstream |
There was a problem hiding this comment.
Thanks for wrestling with my suggestion @alisonelizabeth! I think the code is looking really clean 💪🏻. Great work!
After testing locally I have the following suggestions that we can tackle in a following PR that are quite small:
We could make the code editing experience more natural to users by adding auto closing brackets 👇🏻
Patch for auto closing brackets
diff --git i/packages/kbn-monaco/src/painless/index.ts w/packages/kbn-monaco/src/painless/index.ts
index 3c81f265f9b..514d8ed3b30 100644
--- i/packages/kbn-monaco/src/painless/index.ts
+++ w/packages/kbn-monaco/src/painless/index.ts
@@ -17,10 +17,28 @@
* under the License.
*/
+import { monaco } from '../monaco_imports';
import { ID } from './constants';
import { lexerRules } from './lexer_rules';
import { getSuggestionProvider } from './language';
-export const PainlessLang = { ID, getSuggestionProvider, lexerRules };
+export const PainlessLang = {
+ ID,
+ getSuggestionProvider,
+ lexerRules,
+ languageConfiguration: {
+ brackets: [
+ ['{', '}'],
+ ['[', ']'],
+ ['(', ')'],
+ ],
+ autoClosingPairs: [
+ { open: '{', close: '}' },
+ { open: '[', close: ']' },
+ { open: '(', close: ')' },
+ { open: '"', close: '"' },
+ ],
+ } as monaco.languages.LanguageConfiguration,
+};
export { PainlessContext } from './types';
diff --git i/packages/kbn-monaco/src/register_globals.ts w/packages/kbn-monaco/src/register_globals.ts
index 630467dd817..db97b69c013 100644
--- i/packages/kbn-monaco/src/register_globals.ts
+++ w/packages/kbn-monaco/src/register_globals.ts
@@ -36,6 +36,7 @@ monaco.languages.setMonarchTokensProvider(XJsonLang.ID, XJsonLang.lexerRules);
monaco.languages.setLanguageConfiguration(XJsonLang.ID, XJsonLang.languageConfiguration);
monaco.languages.register({ id: PainlessLang.ID });
monaco.languages.setMonarchTokensProvider(PainlessLang.ID, PainlessLang.lexerRules);
+monaco.languages.setLanguageConfiguration(PainlessLang.ID, PainlessLang.languageConfiguration);
monaco.languages.register({ id: EsqlLang.ID });
monaco.languages.setMonarchTokensProvider(EsqlLang.ID, EsqlLang.lexerRules);
Another minor improvement we can look into is making text the user has typed, like variable names appear in the auto complete list. The only time I saw these names was when I was creating a new variable (but I had already created a variable with that name). So in the gif above, somePi is the name of a function, and when a create a new function I would get that function name suggested to me (which is OK since it is detecting text) but it would be nice if I got the same suggestion when, for instance, returning the result of calling somePi -> return so<complete> further down.
[EDIT]
👏🏻👏🏻 for test coverage!
|
@elasticmachine merge upstream |
💚 Build SucceededMetrics [docs]Async chunks
Distributable file count
Unknown metric groups@kbn/ui-shared-deps asset size
History
To update your PR or re-run it, just comment with: |
|
Thanks @jloleysens for the review!
Thanks for providing the patch! I had considered this, but I received some feedback from the ES engineers that they find this annoying sometimes. I tend to prefer it. I'll add it in a follow-up PR and try to get more feedback around it.
This is tricky. Monaco comes with this kind of autocomplete OOTB. However, once you add custom autocomplete suggestions it no longer works. In other words, if you provide an empty array |
…bana into add-metadata-to-node-details * 'add-metadata-to-node-details' of github.com:phillipb/kibana: [APM] ML anomaly detection integration: Displaying anomaly job results in the Transaction duration chart is not as intended (elastic#84415) Support for painless language autocomplete within monaco (elastic#80577) [Lens] Time scale ui (elastic#83904) removing beta callouts (elastic#84510) [Lens] (Accessibility) add aria-label to chart type icon (elastic#84493) Trusted Apps signer API. (elastic#83661) increase stdout max listeners for legacy logging (elastic#84497) [APM] Service overview: Add throughput chart (elastic#84439) [Discover] Unskip main functional tests (elastic#84300) Uptime overview overhaul (elastic#83406) [APM] Adjust time formats based on the difference between start and end (elastic#84470) [ML] Renaming saved object repair to sync (elastic#84311) [UsageCollection] Remove `formatBulkUpload` and other unused APIs (elastic#84313) [Visualizations] Adds visConfig.title and uiState to build pipeline function (elastic#84456) [Elasticsearch Migration] Update docs re UsageCollection (elastic#84322) TSVB field list performance issue on using annotations (elastic#84407) [Security Solution] Exceptions Cypress tests (elastic#81759) [ML] Fix spaces job ID check (elastic#84404) [Security Solution][Detections] Handle dupes when processing threshold rules (elastic#83062)
* master: (25 commits) [Alerting] fixes buggy default message behaviour (elastic#84202) [Graph] Use new ES client and change license API (elastic#84398) [DOCS] Adds redirect to known plugins page (elastic#84001) Update IndexPatternSelect to get fields from indexPatternService instead of savedObject attributes (elastic#84376) Adding timestamps to created events so the sorting is stable (elastic#84515) [DOCS] Redirects for drilldown links (elastic#83846) [Fleet] Support for showing an Integration Detail Custom (UI Extension) tab (elastic#83805) [Enterprise Search] Migrate shared Schema components (elastic#84381) [Discover] Unskip date_nanos and shard links functional tests (elastic#82878) [APM] ML anomaly detection integration: Displaying anomaly job results in the Transaction duration chart is not as intended (elastic#84415) Support for painless language autocomplete within monaco (elastic#80577) [Lens] Time scale ui (elastic#83904) removing beta callouts (elastic#84510) [Lens] (Accessibility) add aria-label to chart type icon (elastic#84493) Trusted Apps signer API. (elastic#83661) increase stdout max listeners for legacy logging (elastic#84497) [APM] Service overview: Add throughput chart (elastic#84439) [Discover] Unskip main functional tests (elastic#84300) Uptime overview overhaul (elastic#83406) [APM] Adjust time formats based on the difference between start and end (elastic#84470) ...
| const { join } = require('path'); | ||
| const simpleGit = require('simple-git'); | ||
|
|
||
| // Note: The generated whitelists have not yet been merged to master |
There was a problem hiding this comment.
@alisonelizabeth Per #71398 we should refer to allowlists instead of whitelists and blocklists instead of blacklists.

Initial work to add autocomplete functionality for the
painlesslanguage within the monaco editor. This first phase focuses on autocompletion for class and class members given a Painless context. It has been integrated with Painless Lab for ease of testing. Integration across other plugins will be handled in a separate PR.TODO:
painless_labplugin into the@kbn/monacopackageWill open separate PR for integration (reverted via 9b15fdf)Runtimefield in index templates UIScript editor and condition editor in ingest node pipelinesWill open separate PR for integration (reverted via 9b15fdf)@kbn/monaco/painlessSummary
Autocomplete generation
The autocomplete definitions are generated by cloning the ES repo and copying over the allowed classes per context stored here.
Note: This data is currently only available on a feature branch, and has not yet been merged to master. It is also the same information available via the painless context API:
GET /_scripts/painless/_context?context=<context>.The data OOTB is not in a format that can be easily consumed by monaco for autocompletion. Since this is all static content, rather than manipulate the data at runtime, the script that copies the data over also reformats it. All related code can be found under the
scriptsdirectory. The script should only need to be run once per release.There are >30 different painless contexts available. Each context definition is ~1MB. I’ve only added support for a select few contexts for now. Long term, I think we probably need to reevaluate how we handle this if we intend to add more.
Implementation
Please refer to the README for an explanation of the general architecture.
Testing
This work has been integrated in Painless Lab, so testing can be performed there.
What should work?
if,else,for, etc.)editor.tsxfile in Painless Lab to pass fields to the suggestion provider. For example:With this, autocompletion should be available for the
dockeyword, and the available fields should populate when you type the'character inside the bracket, e.g.,doc['].painless_testcontext, but the UI allows you to switch toscoreorfilteras well.Release note
Painless Lab in DevTools now supports autocompletion for keywords, as well as class and class members for the Painless language based on a given context.