From 05706a8d4ef861b50aa77bb8b34ab42722ccdfbc Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 19 Mar 2020 12:25:41 +0100 Subject: [PATCH 1/3] Added language service --- .../painless_lab/public/application/index.tsx | 2 + .../monaco.editor.contributions.ts | 12 ++ .../public/application/register_painless.ts | 195 ------------------ .../plugins/painless_lab/public/lib/index.ts | 7 + .../public/lib/monaco_painless_lang.ts | 174 ++++++++++++++++ x-pack/plugins/painless_lab/public/plugin.tsx | 12 +- .../painless_lab/public/services/index.ts | 7 + .../public/services/language_service.ts | 44 ++++ 8 files changed, 253 insertions(+), 200 deletions(-) create mode 100644 x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts delete mode 100644 x-pack/plugins/painless_lab/public/application/register_painless.ts create mode 100644 x-pack/plugins/painless_lab/public/lib/index.ts create mode 100644 x-pack/plugins/painless_lab/public/lib/monaco_painless_lang.ts create mode 100644 x-pack/plugins/painless_lab/public/services/index.ts create mode 100644 x-pack/plugins/painless_lab/public/services/language_service.ts diff --git a/x-pack/plugins/painless_lab/public/application/index.tsx b/x-pack/plugins/painless_lab/public/application/index.tsx index 48124e61a2eb1..d2ae7b414a9ef 100644 --- a/x-pack/plugins/painless_lab/public/application/index.tsx +++ b/x-pack/plugins/painless_lab/public/application/index.tsx @@ -12,6 +12,8 @@ import { createKibanaReactContext } from '../../../../../src/plugins/kibana_reac import { AppContextProvider } from './context'; import { Main } from './components/main'; +import './monaco.editor.contributions'; + interface AppDependencies { http: CoreSetup['http']; I18nContext: CoreStart['i18n']['Context']; diff --git a/x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts b/x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts new file mode 100644 index 0000000000000..bb573c2fdf026 --- /dev/null +++ b/x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// This file is where we add all of the monaco editor extensions we want to load. +// Importing this file will have the side-effect of registering extensions to the global monaco +// instance. + +// This enables word-wise charactor movements like alt-left. +import 'monaco-editor/esm/vs/editor/contrib/wordOperations/wordOperations'; diff --git a/x-pack/plugins/painless_lab/public/application/register_painless.ts b/x-pack/plugins/painless_lab/public/application/register_painless.ts deleted file mode 100644 index a3952c1941c6e..0000000000000 --- a/x-pack/plugins/painless_lab/public/application/register_painless.ts +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; -export const LANGUAGE_ID = 'painless'; - -/** - * Extends the default type for a Monarch language so we can use - * attribute references (like @keywords to reference the keywords list) - * in the defined tokenizer - */ -interface Language extends monaco.languages.IMonarchLanguage { - default: string; - brackets: any; - keywords: string[]; - symbols: RegExp; - escapes: RegExp; - digits: RegExp; - primitives: string[]; - octaldigits: RegExp; - binarydigits: RegExp; - constants: string[]; - operators: string[]; -} - -function getPainlessLanguage() { - return { - default: '', - // painless does not use < >, so we define our own - brackets: [ - ['{', '}', 'delimiter.curly'], - ['[', ']', 'delimiter.square'], - ['(', ')', 'delimiter.parenthesis'], - ], - keywords: [ - 'if', - 'in', - 'else', - 'while', - 'do', - 'for', - 'continue', - 'break', - 'return', - 'new', - 'try', - 'catch', - 'throw', - 'this', - 'instanceof', - ], - primitives: [ - 'void', - 'boolean', - 'byte', - 'short', - 'char', - 'int', - 'long', - 'float', - 'double', - 'def', - ], - constants: ['true', 'false'], - operators: [ - '=', - '>', - '<', - '!', - '~', - '?', - '?:', - '?.', - ':', - '==', - '===', - '<=', - '>=', - '!=', - '!==', - '&&', - '||', - '++', - '--', - '+', - '-', - '*', - '/', - '&', - '|', - '^', - '%', - '<<', - '>>', - '>>>', - '+=', - '-=', - '*=', - '/=', - '&=', - '|=', - '^=', - '%=', - '<<=', - '>>=', - '>>>=', - '->', - '::', - '=~', - '==~', - ], - symbols: /[=>, so we define our own + brackets: [ + ['{', '}', 'delimiter.curly'], + ['[', ']', 'delimiter.square'], + ['(', ')', 'delimiter.parenthesis'], + ], + keywords: [ + 'if', + 'in', + 'else', + 'while', + 'do', + 'for', + 'continue', + 'break', + 'return', + 'new', + 'try', + 'catch', + 'throw', + 'this', + 'instanceof', + ], + primitives: ['void', 'boolean', 'byte', 'short', 'char', 'int', 'long', 'float', 'double', 'def'], + constants: ['true', 'false'], + operators: [ + '=', + '>', + '<', + '!', + '~', + '?', + '?:', + '?.', + ':', + '==', + '===', + '<=', + '>=', + '!=', + '!==', + '&&', + '||', + '++', + '--', + '+', + '-', + '*', + '/', + '&', + '|', + '^', + '%', + '<<', + '>>', + '>>>', + '+=', + '-=', + '*=', + '/=', + '&=', + '|=', + '^=', + '%=', + '<<=', + '>>=', + '>>>=', + '->', + '::', + '=~', + '==~', + ], + symbols: /[=> { - constructor(ctx: PluginInitializerContext) {} + languageService = new LanguageService(); async setup( { http, getStartServices, uiSettings }: CoreSetup, @@ -71,7 +71,7 @@ export class PainlessLabUIPlugin implements Plugin { + const blob = new Blob([workerSrc], { type: 'application/javascript' }); + return new Worker(window.URL.createObjectURL(blob)); + }, + }; + } + } + + public stop() { + if (CAN_CREATE_WORKER) { + (window as any).MonacoEnvironment = this.originalMonacoEnvironment; + } + } +} From 7ccca0e7a92fe760ad640b32574cf75e2672292b Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 19 Mar 2020 13:11:58 +0100 Subject: [PATCH 2/3] Use the correct monaco instance and add wordwise operations --- packages/kbn-ui-shared-deps/monaco.ts | 2 ++ .../painless_lab/public/application/index.tsx | 2 -- .../application/monaco.editor.contributions.ts | 12 ------------ .../public/services/language_service.ts | 13 +++++++------ 4 files changed, 9 insertions(+), 20 deletions(-) delete mode 100644 x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts diff --git a/packages/kbn-ui-shared-deps/monaco.ts b/packages/kbn-ui-shared-deps/monaco.ts index 570aca86c484c..42801c69a3e2c 100644 --- a/packages/kbn-ui-shared-deps/monaco.ts +++ b/packages/kbn-ui-shared-deps/monaco.ts @@ -25,6 +25,8 @@ import 'monaco-editor/esm/vs/base/worker/defaultWorkerFactory'; import 'monaco-editor/esm/vs/editor/browser/controller/coreCommands.js'; import 'monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget.js'; +import 'monaco-editor/esm/vs/editor/contrib/wordOperations/wordOperations.js'; // Needed for word-wise char navigation + import 'monaco-editor/esm/vs/editor/contrib/suggest/suggestController.js'; // Needed for suggestions import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js'; // Needed for hover import 'monaco-editor/esm/vs/editor/contrib/parameterHints/parameterHints.js'; // Needed for signature diff --git a/x-pack/plugins/painless_lab/public/application/index.tsx b/x-pack/plugins/painless_lab/public/application/index.tsx index d2ae7b414a9ef..48124e61a2eb1 100644 --- a/x-pack/plugins/painless_lab/public/application/index.tsx +++ b/x-pack/plugins/painless_lab/public/application/index.tsx @@ -12,8 +12,6 @@ import { createKibanaReactContext } from '../../../../../src/plugins/kibana_reac import { AppContextProvider } from './context'; import { Main } from './components/main'; -import './monaco.editor.contributions'; - interface AppDependencies { http: CoreSetup['http']; I18nContext: CoreStart['i18n']['Context']; diff --git a/x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts b/x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts deleted file mode 100644 index bb573c2fdf026..0000000000000 --- a/x-pack/plugins/painless_lab/public/application/monaco.editor.contributions.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// This file is where we add all of the monaco editor extensions we want to load. -// Importing this file will have the side-effect of registering extensions to the global monaco -// instance. - -// This enables word-wise charactor movements like alt-left. -import 'monaco-editor/esm/vs/editor/contrib/wordOperations/wordOperations'; diff --git a/x-pack/plugins/painless_lab/public/services/language_service.ts b/x-pack/plugins/painless_lab/public/services/language_service.ts index 01616cf3f4b55..efff9cd0e78d5 100644 --- a/x-pack/plugins/painless_lab/public/services/language_service.ts +++ b/x-pack/plugins/painless_lab/public/services/language_service.ts @@ -4,7 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as monaco from 'monaco-editor'; +// It is important that we use this specific monaco instance so that +// editor settings are registered against the instance our React component +// uses. +import { monaco } from '@kbn/ui-shared-deps/monaco'; + // @ts-ignore import workerSrc from 'raw-loader!monaco-editor/min/vs/base/worker/workerMain.js'; @@ -19,11 +23,8 @@ export class LanguageService { private originalMonacoEnvironment: any; public setup() { - // TODO: Referring to `window.monaco` is a temporary fix for the imported `monaco` module not - // being the same one in use by the editor. - const _monaco = (window as any).monaco as typeof monaco; - _monaco.languages.register({ id: LANGUAGE_ID }); - _monaco.languages.setMonarchTokensProvider(LANGUAGE_ID, monacoPainlessLang); + monaco.languages.register({ id: LANGUAGE_ID }); + monaco.languages.setMonarchTokensProvider(LANGUAGE_ID, monacoPainlessLang); if (CAN_CREATE_WORKER) { this.originalMonacoEnvironment = (window as any).MonacoEnvironment; From b1b7baa394de228a2b0c76795231ecacccd0273b Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 19 Mar 2020 18:31:48 +0100 Subject: [PATCH 3/3] Remove plugin context initializer for now --- x-pack/plugins/painless_lab/public/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/painless_lab/public/index.ts b/x-pack/plugins/painless_lab/public/index.ts index f81218a4fcd96..da357e52af676 100644 --- a/x-pack/plugins/painless_lab/public/index.ts +++ b/x-pack/plugins/painless_lab/public/index.ts @@ -5,9 +5,8 @@ */ import './styles/_index.scss'; -import { PluginInitializerContext } from 'src/core/public'; import { PainlessLabUIPlugin } from './plugin'; -export function plugin(ctx: PluginInitializerContext) { - return new PainlessLabUIPlugin(ctx); +export function plugin() { + return new PainlessLabUIPlugin(); }