[gtksourceview: 10/13] scss.lang: Improve declaration value detection



commit 03ed54da5252a9ab898c12f606d36c0104972308
Author: Jeffery To <jeffery to gmail com>
Date:   Wed Dec 4 05:15:55 2019 +0800

    scss.lang: Improve declaration value detection
    
    This updates the declaration value lookahead regex to correctly
    handle/ignore comments, quoted strings and (function call) parentheses.

 data/language-specs/scss.lang       | 130 ++++++++++++++++++++++++++++++++++--
 tests/syntax-highlighting/file.scss |  71 +++++++++++++++-----
 2 files changed, 179 insertions(+), 22 deletions(-)
---
diff --git a/data/language-specs/scss.lang b/data/language-specs/scss.lang
index 76646576..d52b325c 100644
--- a/data/language-specs/scss.lang
+++ b/data/language-specs/scss.lang
@@ -408,34 +408,150 @@
 
     <context id="scss-declaration-value">
       <start extended="true">
+        (?(DEFINE) (?&lt;escape_interpolation_start&gt; (?: \\ \#{ )+ ) )
+        (?(DEFINE) (?&lt;escape_comment_start&gt;       (?: \\ /\* )+ ) )
+        (?(DEFINE) (?&lt;escape&gt;                     (?: \\ .   )+ ) )
+
+        (?(DEFINE)
+          (?&lt;interpolation_start_chars&gt;
+            (?: (?: \# (?! { ) )+ | (?: (?&lt;! \# ) { )+ )
+          )
+        )
+        (?(DEFINE)
+          (?&lt;comment_start_chars&gt;
+            (?: (?: / (?! \* ) )+ | (?: (?&lt;! / ) \* )+ )
+          )
+        )
+        (?(DEFINE)
+          (?&lt;comment_end_chars&gt;
+            (?: (?: \* (?! / ) )+ | (?: (?&lt;! \* ) / )+ )
+          )
+        )
+
         (?(DEFINE)
           (?&lt;interpolation&gt;  # recursive subpattern to find matching brackets
             \#{
             (?:
               (?&gt;
                 (?:
-                  [^#{}]+ |
-                  (?! \#{ | } ) .
+                  [^\\}#{(/*"']+ |
+                  (?&amp;escape_interpolation_start) |
+                  (?&amp;escape_comment_start) |
+                  (?&amp;escape) |
+                  (?&amp;interpolation_start_chars) |
+                  (?&amp;comment_start_chars)
                 )+
               ) |
-              (?&amp;interpolation)
+              (?&amp;interpolation) |
+              (?&amp;parentheses) |
+              (?&amp;comment) |
+              (?&amp;double_quotes) |
+              (?&amp;single_quotes)
             )*
             }
           )
         )
+        (?(DEFINE)
+          (?&lt;parentheses&gt;  # recursive subpattern to find matching parentheses
+            \(
+            (?:
+              (?&gt;
+                (?:
+                  [^\\)(#{/*"']+ |
+                  (?&amp;escape_interpolation_start) |
+                  (?&amp;escape_comment_start) |
+                  (?&amp;escape) |
+                  (?&amp;interpolation_start_chars) |
+                  (?&amp;comment_start_chars)
+                )+
+              ) |
+              (?&amp;interpolation) |
+              (?&amp;parentheses) |
+              (?&amp;comment) |
+              (?&amp;double_quotes) |
+              (?&amp;single_quotes)
+            )*
+            \)
+          )
+        )
+        (?(DEFINE)
+          (?&lt;comment&gt;  # subpattern to find matching comment delimiters
+            /\*
+            (?:
+              (?&gt;
+                (?:
+                  [^*/#{]+ |
+                  # no escapes
+                  (?&amp;comment_end_chars) |
+                  (?&amp;interpolation_start_chars)
+                )+
+              ) |
+              (?&amp;interpolation)
+            )*
+            \*/
+          )
+        )
+        (?(DEFINE)
+          (?&lt;double_quotes&gt;  # subpattern to find matching double quotes
+            "
+            (?:
+              (?&gt;
+                (?:
+                  [^\\"#{]+ |
+                  (?&amp;escape_interpolation_start) |
+                  (?&amp;escape) |
+                  (?&amp;interpolation_start_chars)
+                )+
+              ) |
+              (?&amp;interpolation)
+            )*
+            "
+          )
+        )
+        (?(DEFINE)
+          (?&lt;single_quotes&gt;  # subpattern to find matching single quotes
+            '
+            (?:
+              (?&gt;
+                (?:
+                  [^\\'#{]+ |
+                  (?&amp;escape_interpolation_start) |
+                  (?&amp;escape) |
+                  (?&amp;interpolation_start_chars)
+                )+
+              ) |
+              (?&amp;interpolation)
+            )*
+            '
+          )
+        )
+
         :
         (?:
           (?!                                 # not the start of a
             \%{css:single-identifier-char} |  #   pseudo-class
             [:\\] |                           #   pseudo-element, escape
-            \#{                               #   interpolation
+            \#{ |                             #   interpolation
+            /\*                               #   comment
           ) |                                 # or
           (?=                                 # ends like a normal declaration
             (?&gt;
               (?:
-                [^;}{#]+ |
-                (?&amp;interpolation)+ |
-                \#+
+                (?&gt;
+                  (?:
+                    [^\\;}{#(/*"']+ |
+                    (?&amp;escape_interpolation_start) |
+                    (?&amp;escape_comment_start) |
+                    (?&amp;escape) |
+                    (?: \# (?! { ) )+ |  # interpolation_start_chars allows {
+                    (?&amp;comment_start_chars)
+                  )+
+                ) |
+                (?&amp;interpolation) |
+                (?&amp;parentheses) |
+                (?&amp;comment) |
+                (?&amp;double_quotes) |
+                (?&amp;single_quotes)
               )*
             )
             \%{css:declaration-value-end}     #   with a semicolon or at the end of a block
diff --git a/tests/syntax-highlighting/file.scss b/tests/syntax-highlighting/file.scss
index f7444094..fc4dfcdb 100644
--- a/tests/syntax-highlighting/file.scss
+++ b/tests/syntax-highlighting/file.scss
@@ -410,8 +410,10 @@ div {
 
 .declarations-or-selectors {
     // declarations
+
     display:block;
     font-family:arial;
+
     font: {
         family: fantasy;
         weight: bold;
@@ -420,33 +422,72 @@ div {
         size: 20px;
         style: italic;
     }
+
     #{$property}:block;
     #{$property}: {
         color: red;
     }
+
     color:#000;
     width:#{$width};
 
+    background-image:url( \( \) \{ { );
+    background-image:url( url( { ) );
+    background-image:url( #{ \) ')' '{' } );
+    background-image:url( /* ) { */ );
+    background-image:url( " ) { " );
+    background-image:url( ' ) { ' );
+
+    margin:#{ \#\{ \} \{ '{' } 10px;
+    margin:#{ url( } { ) } 10px;
+    margin:#{ #{ '{' } } 10px;
+    margin:#{ /* } { */ } 10px;
+    margin:#{ " } { " } 10px;
+    margin:#{ ' } { ' } 10px;
+
+    display:/* { */block;
+    display:/* #{ \*\/ '{' } */block;
+
+    font-family:" \" \{ { ", serif;
+    font-family:" #{ \" "" '{' } ", serif;
+
+    font-family:' \' \{ { ', serif;
+    font-family:' #{ \' '' '{' } ', serif;
+
     // incorrectly highlighted declarations
     display:block
     ;
 
     // selectors
-    input:focus {
-        opacity: 0.5;
-    }
-    div:nth-child(2n+1) {
-       background-color: gray;
-    }
-    div:-moz-full-screen {
-        display: block;
-    }
-    a:#{$state} {
-        color: blue;
-    }
-    #{$selector}:focus {
-        color: blue;
-    }
+    input:focus { opacity: 0.5; }
+    div:nth-child(2n+1) { background-color: gray; }
+    div:-moz-full-screen { display: block; }
+
+    #{$selector}:focus { color: blue; }
+
+    a:#{$state} { color: blue; }
+
+    a:focus[id=\]\;] { color: blue; }
+    a:focus[id=#{ \] "]" ";" }] { color: blue; }
+    a:focus[id=/* ] ; */] { color: blue; }
+    a:focus[id=" ] ; "] { color: blue; }
+    a:focus[id=' ] ; '] { color: blue; }
+
+    a:#{ \#\{ \} \; ';' } { color: blue; }
+    a:#{ url( } ; ) } { color: blue; }
+    a:#{ #{ ';' } } { color: blue; }
+    a:#{ /* } ; */ } { color: blue; }
+    a:#{ " } ; " } { color: blue; }
+    a:#{ ' } ; ' } { color: blue; }
+
+    a:/* ; */focus { color: blue; }
+    a:/* #{ \*\/ ';' } */focus { color: blue; }
+
+    a:focus[id=" ] \" \; ; "] { color: blue; }
+    a:focus[id=" #{ \" "" ';' } "] { color: blue; }
+
+    a:focus[id=' ] \' \; ; '] { color: blue; }
+    a:focus[id=' #{ \' '' ';' } '] { color: blue; }
 }
 
 


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