Skip to content

Commit

Permalink
move painless monaco code to kbn/monaco package
Browse files Browse the repository at this point in the history
  • Loading branch information
alisonelizabeth committed Oct 16, 2020
1 parent 1de9f52 commit f0e31b8
Show file tree
Hide file tree
Showing 20 changed files with 2,195 additions and 46 deletions.
43 changes: 43 additions & 0 deletions packages/kbn-monaco/src/global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { PainlessLang } from './painless';
import { XJsonLang } from './xjson';
// @ts-ignore
import xJsonWorkerSrc from '!!raw-loader!../target/public/xjson.editor.worker.js';
// @ts-ignore
import painlessWorkerSrc from '!!raw-loader!../target/public/painless.editor.worker.js';

const mapLanguageIdToWorker: { [key: string]: any } = {
[XJsonLang.ID]: xJsonWorkerSrc,
[PainlessLang.ID]: painlessWorkerSrc,
};

// @ts-ignore
window.MonacoEnvironment = {
getWorker: (module: string, languageId: string) => {
const workerSrc = mapLanguageIdToWorker[languageId];

if (workerSrc) {
// In kibana we will probably build this once and then load with raw-loader
const blob = new Blob([workerSrc], { type: 'application/javascript' });
return new Worker(URL.createObjectURL(blob));
}
},
};
4 changes: 4 additions & 0 deletions packages/kbn-monaco/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
* under the License.
*/

// Creates web workers
import './global';

export { monaco } from './monaco';
export { XJsonLang } from './xjson';
export { PainlessLang } from './painless';

/* eslint-disable-next-line @kbn/eslint/module_migration */
import * as BarePluginApi from 'monaco-editor/esm/vs/editor/editor.api';
Expand Down
20 changes: 20 additions & 0 deletions packages/kbn-monaco/src/painless/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export const ID = 'painless';
25 changes: 25 additions & 0 deletions packages/kbn-monaco/src/painless/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
* This import registers the painless monaco language contribution
*/
import './language';

export const PainlessLang = { ID: 'painless' };
39 changes: 39 additions & 0 deletions packages/kbn-monaco/src/painless/language.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { monaco } from '../monaco';

import { painlessLanguage } from './painless_lexer_rules';
import { PainlessCompletionAdapter } from './painless_completion';
import { WorkerProxyService } from './worker_proxy_service';
import { ID } from './constants';

const wps = new WorkerProxyService();

monaco.languages.register({ id: ID });

const worker = (...uris: any[]) => {
return wps.getWorker(uris);
};

monaco.languages.onLanguage(ID, async () => {
wps.setup();
});
monaco.languages.setMonarchTokensProvider(ID, painlessLanguage);
monaco.languages.registerCompletionItemProvider(ID, new PainlessCompletionAdapter(worker));
96 changes: 96 additions & 0 deletions packages/kbn-monaco/src/painless/painless_completion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { monaco } from '../monaco';
import { PainlessCompletionResult, PainlessCompletionKind } from './types';

const getCompletionKind = (kind: PainlessCompletionKind): monaco.languages.CompletionItemKind => {
const monacoItemKind = monaco.languages.CompletionItemKind;

switch (kind) {
case 'type':
return monacoItemKind.Interface;
case 'class':
return monacoItemKind.Class;
case 'method':
return monacoItemKind.Method;
case 'constructor':
return monacoItemKind.Constructor;
case 'property':
return monacoItemKind.Property;
}
return monacoItemKind.Property;
};

export class PainlessCompletionAdapter implements monaco.languages.CompletionItemProvider {
// @ts-ignore
constructor(private _worker) {}

public get triggerCharacters(): string[] {
return ['.'];
}

provideCompletionItems(
model: monaco.editor.IReadOnlyModel,
position: monaco.Position,
context: monaco.languages.CompletionContext,
token: monaco.CancellationToken
): Promise<monaco.languages.CompletionList> {
const resource = model.uri;

// Active line characters
const currentLineChars = model.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 0,
endLineNumber: position.lineNumber,
endColumn: position.column,
});

return this._worker(resource)
.then((worker: any) => {
return worker.provideAutocompleteSuggestions(resource.toString(), currentLineChars);
})
.then((completionInfo: PainlessCompletionResult) => {
const wordInfo = model.getWordUntilPosition(position);
const wordRange = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: wordInfo.startColumn,
endColumn: wordInfo.endColumn,
};

const suggestions = completionInfo.suggestions.map(
({ label, insertText, documentation, kind }) => {
return {
label,
insertText,
documentation,
range: wordRange,
kind: getCompletionKind(kind),
};
}
);

return {
isIncomplete: completionInfo.isIncomplete,
suggestions,
};
});
}
}
Loading

0 comments on commit f0e31b8

Please sign in to comment.