Files
grafana/public/app/plugins/datasource/cloudwatch/monarch/CompletionItemProvider.ts
Erik Sundell 467e375fe6 Cloudwatch: Dynamic labels autocomplete (#49794)
* add completeable interface

* add basic labels language

* render monaco editor for label field

* align styling in math expression field

* add unit tests

* fix broken test

* remove unused import

* use theme

* remove comment

* pr feedback

* fix broken imports

* improve test

* make it possible to override code editor styles

* use input styles and align border styles
2022-06-02 10:54:51 +02:00

93 lines
3.3 KiB
TypeScript

import { getTemplateSrv, TemplateSrv } from '@grafana/runtime';
import type { Monaco, monacoTypes } from '@grafana/ui';
import { CloudWatchDatasource } from '../datasource';
import { LinkedToken } from './LinkedToken';
import { linkedTokenBuilder } from './linkedTokenBuilder';
import { LanguageDefinition } from './register';
import { Completeable, StatementPosition, SuggestionKind, TokenTypes } from './types';
type CompletionItem = monacoTypes.languages.CompletionItem;
/*
CompletionItemProvider is an extendable class which needs to implement :
- tokenTypes
- getStatementPosition
- getSuggestionKinds
- getSuggestions
*/
export class CompletionItemProvider implements Completeable {
templateVariables: string[];
datasource: CloudWatchDatasource;
templateSrv: TemplateSrv;
tokenTypes: TokenTypes;
constructor(datasource: CloudWatchDatasource, templateSrv: TemplateSrv = getTemplateSrv()) {
this.datasource = datasource;
this.templateSrv = templateSrv;
this.templateVariables = this.datasource.getVariables();
this.templateSrv = templateSrv;
// implement with more specific tokens when extending this class
this.tokenTypes = {
Parenthesis: 'delimiter.parenthesis',
Whitespace: 'white',
Keyword: 'keyword',
Delimiter: 'delimiter',
Operator: 'operator',
Identifier: 'identifier',
Type: 'type',
Function: 'predefined',
Number: 'number',
String: 'string',
Variable: 'variable',
};
}
// implemented by subclasses, given a token, returns a lexical position in a query
getStatementPosition(currentToken: LinkedToken | null): StatementPosition {
return StatementPosition.Unknown;
}
// implemented by subclasses, given a lexical statement position, returns potential kinds of suggestions
getSuggestionKinds(position: StatementPosition): SuggestionKind[] {
return [];
}
// implemented by subclasses, given potential suggestions kinds, returns suggestion objects for monaco aka "CompletionItem"
getSuggestions(
monaco: Monaco,
currentToken: LinkedToken | null,
suggestionKinds: SuggestionKind[],
statementPosition: StatementPosition,
position: monacoTypes.IPosition
): Promise<CompletionItem[]> {
return Promise.reject([]);
}
// called by registerLanguage and passed to monaco with registerCompletionItemProvider
// returns an object that implements https://microsoft.github.io/monaco-editor/api/interfaces/monaco.languages.CompletionItemProvider.html
getCompletionProvider(monaco: Monaco, languageDefinition: LanguageDefinition) {
return {
triggerCharacters: [' ', '$', ',', '(', "'"], // one of these characters indicates that it is time to look for a suggestion
provideCompletionItems: async (model: monacoTypes.editor.ITextModel, position: monacoTypes.IPosition) => {
const currentToken = linkedTokenBuilder(monaco, languageDefinition, model, position, this.tokenTypes);
const statementPosition = this.getStatementPosition(currentToken);
const suggestionKinds = this.getSuggestionKinds(statementPosition);
const suggestions = await this.getSuggestions(
monaco,
currentToken,
suggestionKinds,
statementPosition,
position
);
return {
suggestions,
};
},
};
}
}