branch: elpa/zig-mode
commit b4170b747ae4c45d145ff8bcb7fafe095e17b4c6
Merge: a0ab9636b8 d78231a5e8
Author: Jacob Young <jacob...@users.noreply.github.com>
Commit: GitHub <nore...@github.com>

    Merge pull request #104 from ziglang/fix-multiline-string-literals
    
    Fix multiline string literals
---
 test/zig-tests.el |  27 ++++++++-
 zig-mode.el       | 175 +++++++++++++++++++++++-------------------------------
 2 files changed, 99 insertions(+), 103 deletions(-)

diff --git a/test/zig-tests.el b/test/zig-tests.el
index dab4bb2dd2..58b5affb51 100644
--- a/test/zig-tests.el
+++ b/test/zig-tests.el
@@ -40,7 +40,7 @@ const string =
 ;"
    '(("const" font-lock-keyword-face)
      ("string" font-lock-variable-name-face)
-     ("\\\\ This newline is NOT escaped \\\n" zig-multiline-string-face))))
+     ("\\\\ This newline is NOT escaped \\" zig-multiline-string-face))))
 
 (ert-deftest test-font-lock-backslash-in-str-literal ()
   (zig-test-font-lock
@@ -100,8 +100,8 @@ const python =
 ;"
    '(("const" font-lock-keyword-face)
      ("python" font-lock-variable-name-face)
-     ("\\\\def main():\n" zig-multiline-string-face)
-     ("\\\\    print(\"Hello, world!\")\n" zig-multiline-string-face))))
+     ("\\\\def main():" zig-multiline-string-face)
+     ("\\\\    print(\"Hello, world!\")" zig-multiline-string-face))))
 
 (ert-deftest test-font-lock-parameters-pointers-and-arrays ()
   (zig-test-font-lock
@@ -164,6 +164,27 @@ const python =
                                ("void" font-lock-type-face)))))
       (zig-test-font-lock test-string expected))))
 
+(ert-deftest test-font-lock-int-types ()
+  (zig-test-font-lock
+   "const Types = .{ u0, i7, u33, i123, u55555 };"
+   '(("const" font-lock-keyword-face)
+     ("Types" font-lock-variable-name-face)
+     ("u0" font-lock-type-face)
+     ("i7" font-lock-type-face)
+     ("u33" font-lock-type-face)
+     ("i123" font-lock-type-face)
+     ("u55555" font-lock-type-face))))
+
+(ert-deftest test-font-lock-escaped-backslash ()
+  (zig-test-font-lock
+   "const a = foo('\\\\', \"C:\\\\\", \\\\
+);"
+   '(("const" font-lock-keyword-face)
+     ("a" font-lock-variable-name-face)
+     ("'\\\\'" font-lock-string-face)
+     ("\"C:\\\\\"" font-lock-string-face)
+     ("\\\\" zig-multiline-string-face))))
+
 ;;===========================================================================;;
 ;; Indentation tests
 
diff --git a/zig-mode.el b/zig-mode.el
index 6742917736..dfccd3f52f 100644
--- a/zig-mode.el
+++ b/zig-mode.el
@@ -163,55 +163,6 @@ If given a SOURCE, execute the CMD on it."
 
     table))
 
-(defconst zig-keywords
-  '(;; Storage
-    "const" "var" "extern" "packed" "export" "pub" "noalias" "inline"
-    "noinline" "comptime" "callconv" "volatile" "allowzero"
-    "align" "linksection" "threadlocal" "addrspace"
-
-    ;; Structure
-    "struct" "enum" "union" "error" "opaque"
-
-    ;; Statement
-    "break" "return" "continue" "asm" "defer" "errdefer" "unreachable"
-    "try" "catch" "async" "nosuspend" "await" "suspend" "resume"
-
-    ;; Conditional
-    "if" "else" "switch" "and" "or" "orelse"
-
-    ;; Repeat
-    "while" "for"
-
-    ;; Other keywords
-    "fn" "usingnamespace" "test"))
-
-(defconst zig-types
-  '(;; Integer types
-    "i2" "u2" "i3" "u3" "i4" "u4" "i5" "u5" "i6" "u6" "i7" "u7" "i8" "u8"
-    "i16" "u16" "i29" "u29" "i32" "u32" "i64" "u64" "i128" "u128"
-    "isize" "usize"
-
-    ;; Floating types
-    "f16" "f32" "f64" "f80" "f128"
-
-    ;; C types
-    "c_char" "c_short" "c_ushort" "c_int" "c_uint" "c_long" "c_ulong"
-    "c_longlong" "c_ulonglong" "c_longdouble"
-
-    ;; Comptime types
-    "comptime_int" "comptime_float"
-
-    ;; Other types
-    "bool" "void" "noreturn" "type" "error" "anyerror" "anyframe" "anytype"
-    "anyopaque"))
-
-(defconst zig-constants
-  '(;; Boolean
-    "true" "false"
-
-    ;; Other constants
-    "null" "undefined"))
-
 (defconst zig-electric-indent-chars
   '(?\; ?\, ?\) ?\] ?\}))
 
@@ -225,9 +176,62 @@ If given a SOURCE, execute the CMD on it."
      (,(concat "@" zig-re-identifier) . font-lock-builtin-face)
 
      ;; Keywords, constants and types
-     (,(regexp-opt zig-keywords  'symbols) . font-lock-keyword-face)
-     (,(regexp-opt zig-constants 'symbols) . font-lock-constant-face)
-     (,(regexp-opt zig-types     'symbols) . font-lock-type-face)
+     (,(rx symbol-start
+           (|
+            ;; Storage
+            "const" "var" "extern" "packed" "export" "pub" "noalias" "inline"
+            "noinline" "comptime" "callconv" "volatile" "allowzero"
+            "align" "linksection" "threadlocal" "addrspace"
+
+            ;; Structure
+            "struct" "enum" "union" "error" "opaque"
+
+            ;; Statement
+            "break" "return" "continue" "asm" "defer" "errdefer" "unreachable"
+            "try" "catch" "async" "nosuspend" "await" "suspend" "resume"
+
+            ;; Conditional
+            "if" "else" "switch" "and" "or" "orelse"
+
+            ;; Repeat
+            "while" "for"
+
+            ;; Other keywords
+            "fn" "usingnamespace" "test")
+           symbol-end)
+      . font-lock-keyword-face)
+
+     (,(rx symbol-start
+           (|
+            ;; Boolean
+            "true" "false"
+
+            ;; Other constants
+            "null" "undefined")
+           symbol-end)
+      . font-lock-constant-face)
+
+     (,(rx symbol-start
+           (|
+            ;; Integer types
+            (: (any ?i ?u) (| ?0 (: (any (?1 . ?9)) (* digit))))
+            "isize" "usize"
+
+            ;; Floating types
+            "f16" "f32" "f64" "f80" "f128"
+
+            ;; C types
+            "c_char" "c_short" "c_ushort" "c_int" "c_uint" "c_long" "c_ulong"
+            "c_longlong" "c_ulonglong" "c_longdouble"
+
+            ;; Comptime types
+            "comptime_int" "comptime_float"
+
+            ;; Other types
+            "bool" "void" "noreturn" "type" "anyerror" "anyframe" "anytype"
+            "anyopaque")
+           symbol-end)
+      . font-lock-type-face)
 
      ;; Type annotations (both variable and type)
      (,zig-re-type-annotation 1 font-lock-variable-name-face)
@@ -357,18 +361,19 @@ This is written mainly to be used as 
`end-of-defun-function' for Zig."
                            (and (not (looking-at " *\\(//[^\n]*\\)?\n"))
                                 (current-column)))
                          (+ prev-block-indent-col zig-indent-offset))))
-                  ;; is-expr-continutation: True if this line continues an
+                  ;; is-expr-continuation: True if this line continues an
                   ;; expression from the previous line, false otherwise.
-                  (is-expr-continutation
+                  (is-expr-continuation
                    (and
                     (not (looking-at "[]});]\\|else"))
                     (save-excursion
                       (zig-skip-backwards-past-whitespace-and-comments)
                       (when (> (point) 1)
                         (backward-char)
-                        (not (looking-at "[,;([{}]")))))))
+                        (or (zig-currently-in-str)
+                            (not (looking-at "[,;([{}]"))))))))
              ;; Now we can calculate indent-col:
-             (if is-expr-continutation
+             (if is-expr-continuation
                  (+ base-indent-col zig-indent-offset)
                base-indent-col)))))
     ;; If point is within the indentation whitespace, move it to the end of the
@@ -379,53 +384,23 @@ This is written mainly to be used as 
`end-of-defun-function' for Zig."
         (indent-line-to indent-col)
       (save-excursion (indent-line-to indent-col)))))
 
-(defun zig-syntax-propertize-to-newline-if-in-multiline-str (end)
-  ;; First, we need to check if we're in a multiline string literal; if we're
-  ;; not, do nothing.
-  (when (zig-currently-in-str)
-    (let ((start (zig-start-of-current-str-or-comment)))
-      (when (save-excursion
-              (goto-char start)
-              (looking-at "\\\\\\\\"))
-        ;; At this point, we've determined that we're within a multiline string
-        ;; literal.  Let `stop' be the position of the closing newline, or
-        ;; `end', whichever comes first.
-        (let ((stop (if (save-excursion
-                          (goto-char start)
-                          (re-search-forward "\n" end t))
-                        (prog1 (match-end 0)
-                          ;; We found the closing newline, so mark it as the
-                          ;; end of this string literal.
-                          (put-text-property (match-beginning 0)
-                                             (match-end 0)
-                                             'syntax-table
-                                             (string-to-syntax "|")))
-                      end)))
-          ;; Zig multiline string literals don't support escapes, so mark all
-          ;; backslashes (up to `stop') as punctation instead of escapes.
-          (save-excursion
-            (goto-char (1+ start))
-            (while (re-search-forward "\\\\" stop t)
-              (put-text-property (match-beginning 0) (match-end 0)
-                                 'syntax-table (string-to-syntax "."))
-              (goto-char (match-end 0))))
-          ;; Move to the end of the string (or `end'), so that
-          ;; zig-syntax-propertize can pick up from there.
-          (goto-char stop))))))
+(defun zig-syntax-propertize-multiline-string (end)
+  (let* ((eol (save-excursion (search-forward "\n" end t)))
+         (stop (or eol end)))
+    (while (search-forward "\\" stop t)
+      (put-text-property (match-beginning 0) (match-end 0) 'syntax-table 
(string-to-syntax ".")))
+    (when eol (put-text-property (- eol 2) (1- eol) 'syntax-table 
(string-to-syntax "|")))
+    (goto-char stop)))
 
 (defun zig-syntax-propertize (start end)
   (goto-char start)
-  (zig-syntax-propertize-to-newline-if-in-multiline-str end)
-  (funcall
-   (syntax-propertize-rules
-    ;; Multiline strings
-    ;; Do not match backslashes that are preceded by single or
-    ;; double-quotes.
-    ("[^\\'\"]c?\\(\\\\\\)\\\\"
-     (1 (prog1 "|"
-          (goto-char (match-end 0))
-          (zig-syntax-propertize-to-newline-if-in-multiline-str end)))))
-   (point) end))
+  (when (eq t (zig-currently-in-str))
+    (zig-syntax-propertize-multiline-string end))
+  (while (search-forward "\\\\" end t)
+    (when (null (save-excursion (backward-char 2) (zig-currently-in-str)))
+      (backward-char)
+      (put-text-property (match-beginning 0) (point) 'syntax-table 
(string-to-syntax "|"))
+      (zig-syntax-propertize-multiline-string end))))
 
 (defun zig-mode-syntactic-face-function (state)
   (save-excursion

Reply via email to