[gtksourceview] python3.lang: add support for Python f-strings



commit 2e6c81ff0508d2a000d74345d2b6628f98b775dd
Author: Rune Riksted <runeriksted gitlab gnome org>
Date:   Tue Jan 4 16:04:17 2022 -0800

    python3.lang: add support for Python f-strings
    
    Fixes #196

 data/language-specs/python3.lang   | 94 ++++++++++++++++++++++++++++++++++++++
 tests/syntax-highlighting/file.py3 | 15 ++++++
 2 files changed, 109 insertions(+)
---
diff --git a/data/language-specs/python3.lang b/data/language-specs/python3.lang
index b1d37e0f..03e0efde 100644
--- a/data/language-specs/python3.lang
+++ b/data/language-specs/python3.lang
@@ -47,6 +47,7 @@
     <style id="function-name"     name="Function Name"         map-to="python:function-name"/>
     <style id="class-name"        name="Class Name"            map-to="python:class-name"/>
     <style id="decorator"         name="Decorator"             map-to="python:decorator"/>
+    <style id="f-string-curly-braces" name="f-string curly braces" map-to="def:special-char"/>
   </styles>
 
   <definitions>
@@ -78,8 +79,33 @@
       </match>
     </context>
 
+    <context id="curly-braces" extend-parent="true">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context ref="python3"/>
+        <context ref="curly-braces"/>
+      </include>
+    </context>
+
+    <context id="f-string-curly-braces" extend-parent="false" class-disabled="string">
+      <start>(\{)</start>
+      <end>(\})</end>
+      <include>
+        <context ref="python3"/>
+        <context ref="curly-braces"/>
+        <context sub-pattern="1" where="start" style-ref="f-string-curly-braces"/>
+        <context sub-pattern="1" where="end" style-ref="f-string-curly-braces"/>
+      </include>
+    </context>
+
+    <context id="escaped-curly-brace" style-ref="escaped-char" extend-parent="true">
+      <match>\{\{</match>
+    </context>
+
     <define-regex id="string-prefix">(b|B)?</define-regex>
     <define-regex id="raw-string-prefix">(r|R|rb|RB|rB|Rb|br|BR|bR|Br)</define-regex>
+    <define-regex id="f-string-prefix">(f|F)</define-regex>
 
     <context id="multiline-double-quoted-string" style-ref="multiline-string" class="string" 
class-disabled="no-spell-check">
       <start>\%{string-prefix}"""</start>
@@ -118,6 +144,69 @@
         <context ref="def:line-continue"/>
       </include>
     </context>
+    <context id="multiline-double-quoted-f-string" class="string" class-disabled="no-spell-check">
+      <start>(\%{f-string-prefix}""")</start>
+      <end>(""")</end>
+      <include>
+        <context ref="escaped-curly-brace"/>
+        <context ref="f-string-curly-braces"/>
+        <context ref="python:escaped-char"/>
+        <context ref="def:line-continue"/>
+        <context style-ref="multiline-string" extend-parent="false" class="string">
+          <match>.</match>
+        </context>
+        <context sub-pattern="1" where="start" style-ref="string"/>
+        <context sub-pattern="1" where="end" style-ref="string"/>
+      </include>
+    </context>
+
+    <context id="multiline-single-quoted-f-string" class="string" class-disabled="no-spell-check">
+      <start>(\%{f-string-prefix}''')</start>
+      <end>(''')</end>
+      <include>
+        <context ref="escaped-curly-brace"/>
+        <context ref="f-string-curly-braces"/>
+        <context ref="python:escaped-char"/>
+        <context ref="def:line-continue"/>
+        <context style-ref="multiline-string" extend-parent="false" class="string">
+          <match>.</match>
+        </context>
+        <context sub-pattern="1" where="start" style-ref="string"/>
+        <context sub-pattern="1" where="end" style-ref="string"/>
+      </include>
+    </context>
+
+    <context id="double-quoted-f-string" end-at-line-end="true" class="string" 
class-disabled="no-spell-check">
+      <start>(\%{f-string-prefix}")</start>
+      <end>(")</end>
+      <include>
+        <context ref="escaped-curly-brace"/>
+        <context ref="f-string-curly-braces"/>
+        <context ref="python:escaped-char"/>
+        <context ref="def:line-continue"/>
+        <context style-ref="string" extend-parent="false" class="string">
+          <match>.</match>
+        </context>
+        <context sub-pattern="1" where="start" style-ref="string"/>
+        <context sub-pattern="1" where="end" style-ref="string"/>
+      </include>
+    </context>
+
+    <context id="single-quoted-f-string" end-at-line-end="true" class="string" 
class-disabled="no-spell-check">
+      <start>(\%{f-string-prefix}')</start>
+      <end>(')</end>
+      <include>
+        <context ref="escaped-curly-brace"/>
+        <context ref="f-string-curly-braces"/>
+        <context ref="python:escaped-char"/>
+        <context ref="def:line-continue"/>
+        <context style-ref="string" extend-parent="false" class="string">
+          <match>.</match>
+        </context>
+        <context sub-pattern="1" where="start" style-ref="string"/>
+        <context sub-pattern="1" where="end" style-ref="string"/>
+      </include>
+    </context>
 
     <context id="multiline-double-quoted-raw-string" style-ref="multiline-string" class="string" 
class-disabled="no-spell-check">
       <start>\%{raw-string-prefix}"""</start>
@@ -207,6 +296,11 @@
         <context ref="double-quoted-string"/>
         <context ref="single-quoted-string"/>
 
+        <context ref="multiline-double-quoted-f-string"/>
+        <context ref="multiline-single-quoted-f-string"/>
+        <context ref="single-quoted-f-string"/>
+        <context ref="double-quoted-f-string"/>
+
         <context ref="multiline-double-quoted-raw-string"/>
         <context ref="multiline-single-quoted-raw-string"/>
         <context ref="double-quoted-raw-string"/>
diff --git a/tests/syntax-highlighting/file.py3 b/tests/syntax-highlighting/file.py3
new file mode 100644
index 00000000..7b7a0160
--- /dev/null
+++ b/tests/syntax-highlighting/file.py3
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import gi
+
+gi.require_version('Gtk', '4.0')
+
+from gi.repository import GLib, GObject, Gtk
+
+my_fstring = f'this is a fstring {something("here")}'
+my_fstring = f"this is a fstring {other('stuff'}"
+
+class MyClass(GObject.Object):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwarg)
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]