[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/swift-mode 2cd111f 351/496: Fix indentation of multiline s
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/swift-mode 2cd111f 351/496: Fix indentation of multiline strings |
Date: |
Sun, 29 Aug 2021 11:34:05 -0400 (EDT) |
branch: elpa/swift-mode
commit 2cd111f6b8b9061b8e3bff5e03e1d6135707b85d
Author: taku0 <mxxouy6x3m_github@tatapa.org>
Commit: taku0 <mxxouy6x3m_github@tatapa.org>
Fix indentation of multiline strings
---
swift-mode-indent.el | 38 +++++++++++++++++++--
swift-mode-lexer.el | 75 ++++++++++++++++++++++++++++++++++++++++++
swift-mode.el | 3 ++
test/swift-files/strings.swift | 36 ++++++++++++++++++++
4 files changed, 149 insertions(+), 3 deletions(-)
diff --git a/swift-mode-indent.el b/swift-mode-indent.el
index 843b3a1..25963ce 100644
--- a/swift-mode-indent.el
+++ b/swift-mode-indent.el
@@ -151,14 +151,20 @@ declaration and its offset is `swift-mode:basic-offset'."
"Return the indentation of the current line."
(back-to-indentation)
- (if (nth 4 (syntax-ppss))
+ (let ((parser-state (syntax-ppss)))
+ (cond
+ ((nth 4 parser-state)
;; If the 4th element of `(syntax-ppss)' is non-nil, the cursor is on
;; the 2nd or following lines of a multiline comment, because:
;;
;; - The 4th element of `(syntax-ppss)' is nil on the comment starter.
;; - We have called `back-to-indentation`.
- (swift-mode:calculate-indent-of-multiline-comment)
- (swift-mode:calculate-indent-of-code)))
+ (swift-mode:calculate-indent-of-multiline-comment))
+
+ ((eq (nth 3 parser-state) t)
+ (swift-mode:calculate-indent-of-multiline-string))
+ (t
+ (swift-mode:calculate-indent-of-code)))))
(defun swift-mode:calculate-indent-of-multiline-comment ()
"Return the indentation of the current line inside a multiline comment."
@@ -180,6 +186,32 @@ declaration and its offset is `swift-mode:basic-offset'."
(swift-mode:calculate-indent-of-multiline-comment)
(swift-mode:indentation (point) 0)))))
+(defun swift-mode:calculate-indent-of-multiline-string ()
+ "Return the indentation of the current line inside a multiline string."
+ (back-to-indentation)
+ (let ((string-beginning-position (nth 8 (syntax-ppss))))
+ (if (looking-at "\"\"\"")
+ ;; The last line.
+ (progn
+ (goto-char string-beginning-position)
+ (swift-mode:calculate-indent-of-expression
+ swift-mode:multiline-statement-offset))
+ (forward-line -1)
+ (back-to-indentation)
+ (if (<= (point) string-beginning-position)
+ ;; The cursor was on the 2nd line of the comment, so aligns with
+ ;; that line with offset.
+ (progn
+ (goto-char string-beginning-position)
+ (swift-mode:calculate-indent-of-expression
+ swift-mode:multiline-statement-offset))
+ ;; The cursor was on the 3rd or following lines of the comment, so
+ ;; aligns with a non-empty preceding line.
+ (if (eolp)
+ ;; The cursor is on an empty line, so seeks a non-empty-line.
+ (swift-mode:calculate-indent-of-multiline-string)
+ (swift-mode:indentation (point) 0))))))
+
(defun swift-mode:calculate-indent-of-code ()
"Return the indentation of the current line outside multiline comments."
(back-to-indentation)
diff --git a/swift-mode-lexer.el b/swift-mode-lexer.el
index 21bdf78..6739b0f 100644
--- a/swift-mode-lexer.el
+++ b/swift-mode-lexer.el
@@ -152,6 +152,81 @@ END is the point after the token."
table))
+(defun swift-mode:syntax-propertize (start end)
+ "Update text properties for multiline strings.
+Mark the beginning of and the end of multiline strings as general string
+delimiters between position START and END.
+Intended for `syntax-propertize-function'"
+ (remove-text-properties start end '(syntax-table nil))
+ (let* ((parser-state (syntax-ppss start))
+ (inside-string (nth 3 parser-state))
+ (comment-nesting (nth 4 parser-state))
+ (comment-beginning-position (nth 8 parser-state)))
+ (cond
+ ((eq inside-string t)
+ (swift-mode:syntax-propertize:end-of-multiline-string end))
+
+ (inside-string
+ (swift-mode:syntax-propertize:end-of-single-line-string end))
+
+ (comment-nesting
+ (goto-char comment-beginning-position)
+ (forward-comment (point-max)))))
+
+ (while (search-forward-regexp
+ (mapconcat #'regexp-quote '("\"\"\"" "\"" "//" "/*") "\\|")
+ end t)
+ (cond
+ ((equal "\"\"\"" (match-string-no-properties 0))
+ (put-text-property (match-beginning 0) (1+ (match-beginning 0))
+ 'syntax-table
+ (string-to-syntax "|"))
+ (swift-mode:syntax-propertize:end-of-multiline-string end))
+
+ ((equal "\"" (match-string-no-properties 0))
+ (swift-mode:syntax-propertize:end-of-single-line-string end))
+
+ ((equal "//" (match-string-no-properties 0))
+ (goto-char (match-beginning 0))
+ (forward-comment (point-max)))
+
+ ((equal "/*" (match-string-no-properties 0))
+ (goto-char (match-beginning 0))
+ (forward-comment (point-max))))))
+
+(defun swift-mode:syntax-propertize:end-of-multiline-string (end)
+ "Move point to the end of multiline string.
+Assuming the cursor is on a multiline string.
+If the end of the string found, put a text property on it.
+If the multiline string go beyond END, stop there."
+ ;; FIXME string interpolation
+ (if (search-forward "\"\"\"" end t)
+ (if (swift-mode:escaped-p (match-beginning 0))
+ (swift-mode:syntax-propertize:end-of-multiline-string end)
+ (put-text-property (1- (point)) (point)
+ 'syntax-table
+ (string-to-syntax "|")))
+ (goto-char end)))
+
+(defun swift-mode:syntax-propertize:end-of-single-line-string (end)
+ "Move point to the end of string.
+Assuming the cursor is on a string.
+If the multiline string go beyond END, stop there."
+ ;; FIXME string interpolation
+ (if (search-forward "\"" end t)
+ (when (swift-mode:escaped-p (match-beginning 0))
+ (swift-mode:syntax-propertize:end-of-single-line-string end))
+ (goto-char end)))
+
+(defun swift-mode:escaped-p (position)
+ "Return t if the POSITION is proceeded by odd number of backslashes.
+Return nil otherwise."
+ (let ((p position)
+ (count 0))
+ (while (eq (char-before p) ?\\)
+ (setq count (1+ count))
+ (setq p (1- p)))
+ (= (mod count 2) 1)))
;;; Lexers
diff --git a/swift-mode.el b/swift-mode.el
index afce622..5c80d1e 100644
--- a/swift-mode.el
+++ b/swift-mode.el
@@ -145,6 +145,9 @@ See `forward-sexp for ARG."
(setq-local adaptive-fill-regexp comment-start-skip)
(setq-local comment-multi-line t)
+ (setq-local parse-sexp-lookup-properties t)
+ (setq-local syntax-propertize-function #'swift-mode:syntax-propertize)
+
(setq-local indent-tabs-mode nil)
(setq-local indent-line-function #'swift-mode:indent-line)
diff --git a/test/swift-files/strings.swift b/test/swift-files/strings.swift
new file mode 100644
index 0000000..a961be5
--- /dev/null
+++ b/test/swift-files/strings.swift
@@ -0,0 +1,36 @@
+// swift-mode:test:eval (setq-local swift-mode:basic-offset 4)
+// swift-mode:test:eval (setq-local swift-mode:parenthesized-expression-offset
2)
+// swift-mode:test:eval (setq-local swift-mode:multiline-statement-offset 2)
+// swift-mode:test:eval (setq-local swift-mode:switch-case-offset 0)
+
+func f() {
+ let x = """
+ aaa
+ "
+ aaa
+ ""
+ aaa
+ \"""
+ aaa
+ ""
+ aaa
+ "
+ aaa
+ """ +
+ "abc"
+
+ let x = """
+ aaa
+ "
+ aaa // swift-mode:test:keep-indent
+ ""
+ aaa
+ \"""
+ aaa
+ ""
+ aaa
+ "
+ aaa
+ """ +
+ "abc"
+}
- [nongnu] elpa/swift-mode b6512fa 325/496: Fix indentation of attributes, (continued)
- [nongnu] elpa/swift-mode b6512fa 325/496: Fix indentation of attributes, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 1d43501 330/496: Fix indentation of attributes at begging of the buffer., ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 193de68 327/496: Fix end-of-defun at eob, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode a07be7a 335/496: Fix `swift-mode:beginning-of-defun`, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode f03db1a 331/496: Fix indentation of switch., ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode a489024 344/496: indent-new-comment-line: Inherit slashes from the previous line, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 75cbae2 345/496: Bump version to 2.2.3, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 42669da 343/496: Fix indentation for keywords used as parameter names, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 0cab4b2 346/496: Fix indentation for catch blocks without patterns, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 92f8eba 349/496: Update README.md, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 2cd111f 351/496: Fix indentation of multiline strings,
ELPA Syncer <=
- [nongnu] elpa/swift-mode 3bcdf32 353/496: Add more keywords with number sign, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 030b1b8 356/496: Update documentations and wordings, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode d68af3c 365/496: Update copyright, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 359efc0 379/496: Fix indentation of function parameter clauses, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 25944c2 378/496: Add test for beginning/end-of-defun, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode ea029a0 370/496: Suppress implicit semicolons inside interpolated expressions, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode b5602c1 375/496: Add beginning/end-of-sentence to README.md, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 18c3dc4 376/496: Bump version to 4.0.0, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 27e959e 385/496: Handle unmatched parens correctly, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode abf3426 392/496: Add support for highlighting function calls / properties / enum cases, ELPA Syncer, 2021/08/29