Repository: pabluk/pygments-promql (language: python)

Issue:
Complex PromQL expressions
Hiyah,

does this packages support more complex PromQL expressions ?

I tried with one but the label set is not highlighted properly.

See the following for an example:
![Screenshot 2021-04-22 at 18 27 31](https://user-images.githubusercontent.com/9629314/115750555-9419b000-a398-11eb-9068-977bf4abd3d5.png)

Complex PromQL expressions
Hiyah,

does this packages support more complex PromQL expressions ?

I tried with one but the label set is not highlighted properly.

See the following for an example:
![Screenshot 2021-04-22 at 18 27 31](https://user-images.githubusercontent.com/9629314/115750555-9419b000-a398-11eb-9068-977bf4abd3d5.png)



Discussion / hints:
Hi @ocervell, it should also work with that kind of complex expressions.
In any case your expression seems to be a good test case, could you please paste a text version of it? I would like to included in the test suite and fix the output.

Thanks for report it :+1: 
Hi @ocervell, it should also work with that kind of complex expressions.
In any case your expression seems to be a good test case, could you please paste a text version of it? I would like to included in the test suite and fix the output.

Thanks for report it :+1: 

Fix patch:
diff --git a/pygments_promql/__init__.py b/pygments_promql/__init__.py
index 3cbc32f..f220920 100644
--- a/pygments_promql/__init__.py
+++ b/pygments_promql/__init__.py
@@ -167,7 +167,7 @@ class PromQLLexer(RegexLexer):
             (r"\s+", Whitespace),
             (r",", Punctuation),
             (
-                r'([_a-zA-Z][_a-zA-Z0-9]*?)(\s*?)(=|!=|=~|~!)(\s*?)(")(.*?)(")',
+                r"""([_a-zA-Z][_a-zA-Z0-9]*?)(\s*?)(=|!=|=~|!~)(\s*?)("|')(.*?)("|')""",
                 bygroups(
                     Name.Label,
                     Whitespace,


Test patch:
diff --git a/tests/test_promql.py b/tests/test_promql.py
index 7981e68..94f39b9 100644
--- a/tests/test_promql.py
+++ b/tests/test_promql.py
@@ -308,3 +308,98 @@ def test_function_multi_line2(lexer):
         (Token.Text.Whitespace, "\n"),
     ]
     assert list(lexer.get_tokens(fragment)) == tokens
+
+
+def test_complex_exp_double_quotes(lexer):
+    fragment = u'(sum(rate(metric_test_app{app="turtle",proc="web"}[2m])) by(node))\n'
+    tokens = [
+        (Token.Operator, "("),
+        (Token.Keyword, "sum"),
+        (Token.Operator, "("),
+        (Token.Keyword.Reserved, "rate"),
+        (Token.Operator, "("),
+        (Token.Name.Variable, "metric_test_app"),
+        (Token.Punctuation, "{"),
+        (Token.Name.Label, "app"),
+        (Token.Operator, "="),
+        (Token.Punctuation, '"'),
+        (Token.Literal.String, "turtle"),
+        (Token.Punctuation, '"'),
+        (Token.Punctuation, ","),
+        (Token.Name.Label, "proc"),
+        (Token.Operator, "="),
+        (Token.Punctuation, '"'),
+        (Token.Literal.String, "web"),
+        (Token.Punctuation, '"'),
+        (Token.Punctuation, "}"),
+        (Token.Punctuation, "["),
+        (Token.Literal.String, "2m"),
+        (Token.Punctuation, "]"),
+        (Token.Operator, ")"),
+        (Token.Operator, ")"),
+        (Token.Text.Whitespace, " "),
+        (Token.Keyword, "by"),
+        (Token.Operator, "("),
+        (Token.Name.Variable, "node"),
+        (Token.Operator, ")"),
+        (Token.Operator, ")"),
+        (Token.Text.Whitespace, "\n"),
+    ]
+    assert list(lexer.get_tokens(fragment)) == tokens
+
+
+def test_complex_exp_single_quotes(lexer):
+    fragment = u"(sum(rate(metric_test_app{app='turtle',proc='web'}[2m])) by(node))\n"
+    tokens = [
+        (Token.Operator, "("),
+        (Token.Keyword, "sum"),
+        (Token.Operator, "("),
+        (Token.Keyword.Reserved, "rate"),
+        (Token.Operator, "("),
+        (Token.Name.Variable, "metric_test_app"),
+        (Token.Punctuation, "{"),
+        (Token.Name.Label, "app"),
+        (Token.Operator, "="),
+        (Token.Punctuation, "'"),
+        (Token.Literal.String, "turtle"),
+        (Token.Punctuation, "'"),
+        (Token.Punctuation, ","),
+        (Token.Name.Label, "proc"),
+        (Token.Operator, "="),
+        (Token.Punctuation, "'"),
+        (Token.Literal.String, "web"),
+        (Token.Punctuation, "'"),
+        (Token.Punctuation, "}"),
+        (Token.Punctuation, "["),
+        (Token.Literal.String, "2m"),
+        (Token.Punctuation, "]"),
+        (Token.Operator, ")"),
+        (Token.Operator, ")"),
+        (Token.Text.Whitespace, " "),
+        (Token.Keyword, "by"),
+        (Token.Operator, "("),
+        (Token.Name.Variable, "node"),
+        (Token.Operator, ")"),
+        (Token.Operator, ")"),
+        (Token.Text.Whitespace, "\n"),
+    ]
+    assert list(lexer.get_tokens(fragment)) == tokens
+
+
+def test_matching_operator_no_regexmatch(lexer):
+    fragment = u"metric_test_app{status!~'(4|5)..'}[2m]"
+    tokens = [
+        (Token.Name.Variable, "metric_test_app"),
+        (Token.Punctuation, "{"),
+        (Token.Name.Label, "status"),
+        (Token.Operator, "!~"),
+        (Token.Punctuation, "'"),
+        (Token.Literal.String, "(4|5).."),
+        (Token.Punctuation, "'"),
+        (Token.Punctuation, "}"),
+        (Token.Punctuation, "["),
+        (Token.Literal.String, "2m"),
+        (Token.Punctuation, "]"),
+        (Token.Text.Whitespace, "\n"),
+    ]
+    assert list(lexer.get_tokens(fragment)) == tokens