branch: elpa/dart-mode
commit 6e1c42f05dbaefe46ea669c470d0313f6e540113
Author: Brady Trainor <[email protected]>
Commit: Brady Trainor <[email protected]>

    Fontify string interpolation
    
    For now entire string interpolation expressions are fontified
    uniformly with font-lock-variable-name-face.
    
    However the matcher for identifiers ($name) and expressions (${2 < 3})
    are grouped, so that the sigil, delimiters, identifiers and
    expressions can be fontified differently.
    
    The following example suggests the freedom allowed with these groups.
    
    (dart--string-interpolation-id-func  (1 dart-int-id-sigil-face  t)
                                         (2 dart-int-id-id-face     t))
    (dart--string-interpolation-exp-func (1 dart-int-exp-sigil-face t)
                                         (2 dart-int-exp-delim-face t)
                                         (3 dart-int-exp-exp-face   t)
                                         (4 dart-int-exp-delim-face t))
---
 dart-mode.el | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/dart-mode.el b/dart-mode.el
index ab2f3c7..fb66412 100644
--- a/dart-mode.el
+++ b/dart-mode.el
@@ -407,6 +407,65 @@ Returns nil if `dart-sdk-path' is nil."
 
 (setq dart--types-re (rx (eval (dart--identifier 'upper))))
 
+(defun dart--string-interpolation-id-func (limit)
+  (catch 'result
+    (let (data end syntax)
+      (while (re-search-forward (rx (group ?$)
+                                    (group (zero-or-more ?_)
+                                           lower
+                                           (zero-or-more (or ?_ alnum))))
+                                limit t)
+        (setq data (match-data))
+        (setq end (match-end 2))
+        (setq syntax (syntax-ppss))
+        (when (and (nth 3 syntax)
+                   (or (= (nth 8 syntax) 1)
+                       (not (eq (char-before (nth 8 syntax)) ?r))))
+          (set-match-data data)
+          (goto-char end)
+          (throw 'result t))
+        (when end
+          (goto-char end)))
+      (throw 'result nil))))
+
+(defun dart--string-interpolation-exp-func (limit)
+  ;; While there are still ${ in non-raw strings to be found.
+  ;; While point has positive depth and is in string.
+  ;; Move forward.
+  ;; If depth hits zero, return match.
+  ;; If we leave string, search again.
+  ;; When we run out of search results, return nil.
+  (catch 'result
+    (let (sigil beg open close end syntax depth)
+      (while (and (search-forward "${" limit t)
+                  (save-excursion
+                    (and (nth 3 (syntax-ppss))
+                         (not (eq (char-before (nth 8 (syntax-ppss))) ?r)))))
+        (setq open (point))
+        (setq beg (- open 1))
+        (setq sigil (- open 2))
+        (setq depth 1)
+        (while (and (> depth 0)
+                    (< (point) limit)
+                    (nth 3 (syntax-ppss)))
+          (setq depth (+ depth (pcase (char-after)
+                                 (?\{ 1)
+                                 (?\} -1)
+                                 (_ 0))))
+          (forward-char))
+        (setq end (point))
+        (when (= depth 0)
+          (setq close (1- end))
+          (set-match-data (list sigil end
+                                sigil beg
+                                beg open
+                                open close
+                                close end))
+          (goto-char end)
+          (throw 'result t))
+        (goto-char end))
+      (throw 'result nil))))
+
 (defun dart--function-declaration-func (limit)
   (catch 'result
     (let (beg end)
@@ -515,7 +574,9 @@ Returns nil if `dart-sdk-path' is nil."
           . (dart--declared-identifier-next-func
              nil
              nil
-             (0 font-lock-variable-name-face))))))
+             (0 font-lock-variable-name-face)))
+         (dart--string-interpolation-id-func   (0 font-lock-variable-name-face 
t))
+         (dart--string-interpolation-exp-func  (0 font-lock-variable-name-face 
t)))))
 
 (setq dart-string-delimiter (rx (and
                             ;; Match even number of backslashes.

Reply via email to