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