branch: elpa/swift-mode
commit b1334e1b0eeeb8a5d0d6f5e15e17c03fd939bb1c
Author: ap4y <l...@pisem.net>
Commit: ap4y <l...@pisem.net>

    Highlight interpolation expression via syntactic fontification
---
 swift-mode.el           | 37 +++++++++++++++++++++++++++++++++++++
 test/font-lock-tests.el |  2 ++
 2 files changed, 39 insertions(+)

diff --git a/swift-mode.el b/swift-mode.el
index e3e49a4..febdd43 100644
--- a/swift-mode.el
+++ b/swift-mode.el
@@ -324,8 +324,44 @@
     ;; consistency with C modes.
     (,(rx bow "import" eow (+ space) (group (+ word)))
      1 font-lock-string-face)
+
+    ;; String interpolation
+    ;;
+    ;; Highlight interpolation expression as identifier.
+    (swift-match-interpolation 0 font-lock-variable-name-face t)
     ))
 
+(defun swift-syntax-propertize-function (start end)
+  "Syntactic keywords for Swift mode."
+  (let (case-fold-search)
+    (goto-char start)
+    (remove-text-properties start end '(swift-interpolation-match-data))
+    (funcall
+     (syntax-propertize-rules
+      ((rx (or line-start (not (any "\\")))
+           (zero-or-more "\\\\")
+           (group "\\(" (zero-or-more any) ")"))
+       (0 (ignore (swift-syntax-propertize-interpolation)))))
+     start end)))
+
+(defun swift-syntax-propertize-interpolation ()
+  (let* ((beg (match-beginning 0))
+         (context (save-excursion (save-match-data (syntax-ppss beg)))))
+    (put-text-property beg (1+ beg) 'swift-interpolation-match-data
+                       (cons (nth 3 context) (match-data)))))
+
+(defun swift-match-interpolation (limit)
+  (let ((pos (next-single-char-property-change (point) 
'swift-interpolation-match-data
+                                               nil limit)))
+    (when (and pos (> pos (point)))
+      (goto-char pos)
+      (let ((value (get-text-property pos 'swift-interpolation-match-data)))
+        (if (eq (car value) ?\")
+            (progn
+              (set-match-data (cdr value))
+              t)
+          (swift-match-interpolation limit))))))
+
 ;;; Imenu
 
 (defun swift-mode--mk-regex-for-def (keyword)
@@ -495,6 +531,7 @@ You can send text to the REPL process from other buffers 
containing source.
   :group 'swift
   :syntax-table swift-mode-syntax-table
   (setq font-lock-defaults '((swift-font-lock-keywords) nil nil))
+  (setq-local syntax-propertize-function #'swift-syntax-propertize-function)
 
   (setq-local imenu-generic-expression swift-mode--imenu-generic-expression)
 
diff --git a/test/font-lock-tests.el b/test/font-lock-tests.el
index 361ba62..acd14b0 100644
--- a/test/font-lock-tests.el
+++ b/test/font-lock-tests.el
@@ -186,6 +186,8 @@ test will fail."
 (check-face class/base-type-has-type-face/4 font-lock-type-face "class T<U> : 
{{Base}}")
 (check-face class/base-type-colon-has-default-face/1 nil "class T {{:}} Base")
 
+(check-face string-interpolation/has-variable-face/1 
font-lock-variable-name-face "\"foo {{\\\(bar)}}\"")
+
 (provide 'font-lock-tests)
 
 ;;; font-lock-tests.el ends here

Reply via email to