diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts index 3ef3f299bdb..6c5f96ebe97 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts @@ -74,7 +74,7 @@ export function getCompletionProvider( }; return { - triggerCharacters: ['{', ',', '[', '(', '=', '~'], + triggerCharacters: ['{', ',', '[', '(', '=', '~', ' '], provideCompletionItems, }; } diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.test.ts b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.test.ts index 860fa4ad399..f8232eb56b0 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.test.ts +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.test.ts @@ -46,6 +46,8 @@ describe('intent', () => { assertIntent('something{}[^]', { type: 'ALL_DURATIONS', }); + + assertIntent('something{label~^}', null); }); it('handles label names', () => { diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.ts b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.ts index 4f1bf2f6293..d37497a9509 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.ts +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/intent.ts @@ -389,7 +389,20 @@ function resolveDurations(node: SyntaxNode, text: string, pos: number): Intent { }; } +function subTreeHasError(node: SyntaxNode): boolean { + return getNodeInSubtree(node, ERROR_NODE_NAME) !== null; +} + function resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Intent | null { + // for example `something{^}` + + // there are some false positives that can end up in this situation, that we want + // to eliminate, for example: `something{a~^}` + // basically, if this subtree contains any error-node, we stop + if (subTreeHasError(node)) { + return null; + } + const metricNameNode = walk(node, [ ['parent', 'VectorSelector'], ['firstChild', 'MetricIdentifier'],