branch: elpa/zig-mode
commit d78231a5e8ac9193e2dd480d6bd854e46dcccc63
Author: Jacob Young <[email protected]>
Commit: Jacob Young <[email protected]>
fix multiline string literals
---
test/zig-tests.el | 16 ++++++++++---
zig-mode.el | 67 ++++++++++++++++---------------------------------------
2 files changed, 32 insertions(+), 51 deletions(-)
diff --git a/test/zig-tests.el b/test/zig-tests.el
index 4ac3626a08..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
@@ -175,6 +175,16 @@ const python =
("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 f2b8831d06..dfccd3f52f 100644
--- a/zig-mode.el
+++ b/zig-mode.el
@@ -361,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
@@ -383,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