CompletionItemProvider.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { getTemplateSrv, TemplateSrv } from '@grafana/runtime';
  2. import type { Monaco, monacoTypes } from '@grafana/ui';
  3. import { CloudWatchDatasource } from '../../datasource';
  4. import { CompletionItemProvider } from '../../monarch/CompletionItemProvider';
  5. import { LinkedToken } from '../../monarch/LinkedToken';
  6. import { TRIGGER_SUGGEST } from '../../monarch/commands';
  7. import { SuggestionKind, CompletionItemPriority, StatementPosition } from '../../monarch/types';
  8. import {
  9. METRIC_MATH_FNS,
  10. METRIC_MATH_KEYWORDS,
  11. METRIC_MATH_OPERATORS,
  12. METRIC_MATH_PERIODS,
  13. METRIC_MATH_STATISTIC_KEYWORD_STRINGS,
  14. } from '../language';
  15. import { getStatementPosition } from './statementPosition';
  16. import { getSuggestionKinds } from './suggestionKind';
  17. import { MetricMathTokenTypes } from './types';
  18. type CompletionItem = monacoTypes.languages.CompletionItem;
  19. export class MetricMathCompletionItemProvider extends CompletionItemProvider {
  20. constructor(datasource: CloudWatchDatasource, templateSrv: TemplateSrv = getTemplateSrv()) {
  21. super(datasource, templateSrv);
  22. this.getStatementPosition = getStatementPosition;
  23. this.getSuggestionKinds = getSuggestionKinds;
  24. this.tokenTypes = MetricMathTokenTypes;
  25. }
  26. async getSuggestions(
  27. monaco: Monaco,
  28. currentToken: LinkedToken | null,
  29. suggestionKinds: SuggestionKind[],
  30. statementPosition: StatementPosition,
  31. position: monacoTypes.IPosition
  32. ): Promise<CompletionItem[]> {
  33. let suggestions: CompletionItem[] = [];
  34. const invalidRangeToken = currentToken?.isWhiteSpace() || currentToken?.isParenthesis();
  35. const range =
  36. invalidRangeToken || !currentToken?.range ? monaco.Range.fromPositions(position) : currentToken?.range;
  37. const toCompletionItem = (value: string, rest: Partial<CompletionItem> = {}) => {
  38. const item: CompletionItem = {
  39. label: value,
  40. insertText: value,
  41. kind: monaco.languages.CompletionItemKind.Field,
  42. range,
  43. sortText: CompletionItemPriority.Medium,
  44. ...rest,
  45. };
  46. return item;
  47. };
  48. function addSuggestion(value: string, rest: Partial<CompletionItem> = {}) {
  49. suggestions = [...suggestions, toCompletionItem(value, rest)];
  50. }
  51. for (const suggestion of suggestionKinds) {
  52. switch (suggestion) {
  53. case SuggestionKind.FunctionsWithArguments:
  54. METRIC_MATH_FNS.map((f) =>
  55. addSuggestion(f, {
  56. insertText: f === 'SEARCH' ? `${f}('$0')` : `${f}($0)`,
  57. insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
  58. command: TRIGGER_SUGGEST,
  59. kind: monaco.languages.CompletionItemKind.Function,
  60. })
  61. );
  62. break;
  63. case SuggestionKind.KeywordArguments:
  64. METRIC_MATH_KEYWORDS.map((s) =>
  65. addSuggestion(s, {
  66. insertText: s,
  67. command: TRIGGER_SUGGEST,
  68. kind: monaco.languages.CompletionItemKind.Keyword,
  69. sortText: CompletionItemPriority.MediumHigh,
  70. })
  71. );
  72. break;
  73. case SuggestionKind.Statistic:
  74. METRIC_MATH_STATISTIC_KEYWORD_STRINGS.map((s) =>
  75. addSuggestion(s, {
  76. insertText: `'${s}', `,
  77. command: TRIGGER_SUGGEST,
  78. })
  79. );
  80. break;
  81. case SuggestionKind.Operators:
  82. METRIC_MATH_OPERATORS.map((s) =>
  83. addSuggestion(s, {
  84. insertText: `${s} `,
  85. command: TRIGGER_SUGGEST,
  86. })
  87. );
  88. break;
  89. case SuggestionKind.Period:
  90. METRIC_MATH_PERIODS.map((s, idx) =>
  91. addSuggestion(s.toString(), {
  92. kind: monaco.languages.CompletionItemKind.Value,
  93. sortText: String.fromCharCode(97 + idx), // converts index 0, 1 to "a", "b", etc needed to show the time periods in numerical order
  94. })
  95. );
  96. break;
  97. }
  98. }
  99. // always suggest template variables
  100. this.templateVariables.map((v) => {
  101. addSuggestion(v, {
  102. range,
  103. label: v,
  104. insertText: v,
  105. kind: monaco.languages.CompletionItemKind.Variable,
  106. sortText: CompletionItemPriority.Low,
  107. });
  108. });
  109. return suggestions;
  110. }
  111. }