From 90e7909cef1f5b5f3ebc73a4b4c75127efec34b7 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Wed, 12 Feb 2020 15:45:36 +0100 Subject: [PATCH] Loki, Prometheus: Fix PromQL and LogQL syntax highlighting (#21944) * Loki, Prometheus: Fix syntax to not highlight # in quotes as a comment in queryField * Loki, Prometheus: Fix syntax to not highlight # in quotes as a comment in queryField * Fix regex * PromQL, LogQL: Update syntax * LogQL, PromQL highlighting: Add tests (cherry picked from commit 1448767c0822b790823b157a86073f8b3c171645) --- .../plugins/datasource/loki/syntax.test.ts | 22 +++++++++++++++++++ public/app/plugins/datasource/loki/syntax.ts | 9 +++++--- .../datasource/prometheus/promql.test.ts | 22 +++++++++++++++++++ .../plugins/datasource/prometheus/promql.ts | 8 +++++-- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 public/app/plugins/datasource/loki/syntax.test.ts create mode 100644 public/app/plugins/datasource/prometheus/promql.test.ts diff --git a/public/app/plugins/datasource/loki/syntax.test.ts b/public/app/plugins/datasource/loki/syntax.test.ts new file mode 100644 index 00000000000..7a5fcf18568 --- /dev/null +++ b/public/app/plugins/datasource/loki/syntax.test.ts @@ -0,0 +1,22 @@ +import syntax from './syntax'; +import Prism from 'prismjs'; + +describe('Loki syntax', () => { + it('should highlight Loki query correctly', () => { + expect(Prism.highlight('{key="val#ue"}', syntax, 'loki')).toBe( + '{key="val#ue"}' + ); + expect(Prism.highlight('{key="#value"}', syntax, 'loki')).toBe( + '{key="#value"}' + ); + expect(Prism.highlight('{key="value#"}', syntax, 'loki')).toBe( + '{key="value#"}' + ); + expect(Prism.highlight('#test{key="value"}', syntax, 'loki')).toBe( + '#test{key="value"}' + ); + expect(Prism.highlight('{key="value"}#test', syntax, 'loki')).toBe( + '{key="value"}#test' + ); + }); +}); diff --git a/public/app/plugins/datasource/loki/syntax.ts b/public/app/plugins/datasource/loki/syntax.ts index f42c337eacc..fc2406479cf 100644 --- a/public/app/plugins/datasource/loki/syntax.ts +++ b/public/app/plugins/datasource/loki/syntax.ts @@ -69,8 +69,7 @@ export const FUNCTIONS = [...AGGREGATION_OPERATORS, ...RANGE_VEC_FUNCTIONS]; const tokenizer: Grammar = { comment: { - pattern: /(^|[^\n])#.*/, - lookbehind: true, + pattern: /#.*/, }, 'context-aggregation': { pattern: /((without|by)\s*)\([^)]*\)/, // by () @@ -85,11 +84,15 @@ const tokenizer: Grammar = { }, 'context-labels': { pattern: /\{[^}]*(?=})/, - lookbehind: true, + greedy: true, inside: { + comment: { + pattern: /#.*/, + }, 'label-key': { pattern: /[a-z_]\w*(?=\s*(=|!=|=~|!~))/, alias: 'attr-name', + greedy: true, }, 'label-value': { pattern: /"(?:\\.|[^\\"])*"/, diff --git a/public/app/plugins/datasource/prometheus/promql.test.ts b/public/app/plugins/datasource/prometheus/promql.test.ts new file mode 100644 index 00000000000..2b0cc20fd1e --- /dev/null +++ b/public/app/plugins/datasource/prometheus/promql.test.ts @@ -0,0 +1,22 @@ +import promql from './promql'; +import Prism from 'prismjs'; + +describe('Loki syntax', () => { + it('should highlight Loki query correctly', () => { + expect(Prism.highlight('{key="val#ue"}', promql, 'promql')).toBe( + '{key="val#ue"}' + ); + expect(Prism.highlight('{key="#value"}', promql, 'promql')).toBe( + '{key="#value"}' + ); + expect(Prism.highlight('{key="value#"}', promql, 'promql')).toBe( + '{key="value#"}' + ); + expect(Prism.highlight('#test{key="value"}', promql, 'promql')).toBe( + '#test{key="value"}' + ); + expect(Prism.highlight('{key="value"}#test', promql, 'promql')).toBe( + '{key="value"}#test' + ); + }); +}); diff --git a/public/app/plugins/datasource/prometheus/promql.ts b/public/app/plugins/datasource/prometheus/promql.ts index 0bde2da9c2f..d4b68200ba6 100644 --- a/public/app/plugins/datasource/prometheus/promql.ts +++ b/public/app/plugins/datasource/prometheus/promql.ts @@ -377,8 +377,7 @@ export const FUNCTIONS = [ const tokenizer = { comment: { - pattern: /(^|[^\n])#.*/, - lookbehind: true, + pattern: /#.*/, }, 'context-aggregation': { pattern: /((by|without)\s*)\([^)]*\)/, // by () @@ -393,10 +392,15 @@ const tokenizer = { }, 'context-labels': { pattern: /\{[^}]*(?=})/, + greedy: true, inside: { + comment: { + pattern: /#.*/, + }, 'label-key': { pattern: /[a-z_]\w*(?=\s*(=|!=|=~|!~))/, alias: 'attr-name', + greedy: true, }, 'label-value': { pattern: /"(?:\\.|[^\\"])*"/,