Skip to content

Commit d59cae7

Browse files
committed
Fix indentation of string interpolations
1 parent 55ea958 commit d59cae7

File tree

4 files changed

+352
-54
lines changed

4 files changed

+352
-54
lines changed

swift-mode-indent.el

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ Intended for debugging."
102102

103103
(defconst swift-mode:expression-parent-tokens
104104
(append swift-mode:statement-parent-tokens
105-
'(\, < supertype-: "where" "if" "guard" "while" "for" "catch"))
105+
'(\, < supertype-: "where" "if" "guard" "while" "for" "catch"
106+
string-chunk-before-interpolation))
106107
"Parent tokens for expressions.")
107108

108109
(defvar-local swift-mode:anchor-overlay nil)
@@ -163,6 +164,7 @@ declaration and its offset is `swift-mode:basic-offset'."
163164

164165
((eq (nth 3 parser-state) t)
165166
(swift-mode:calculate-indent-of-multiline-string))
167+
166168
(t
167169
(swift-mode:calculate-indent-of-code)))))
168170

@@ -189,14 +191,17 @@ declaration and its offset is `swift-mode:basic-offset'."
189191
(defun swift-mode:calculate-indent-of-multiline-string ()
190192
"Return the indentation of the current line inside a multiline string."
191193
(back-to-indentation)
192-
(let ((string-beginning-position (nth 8 (syntax-ppss))))
194+
(let ((string-beginning-position
195+
(save-excursion (swift-mode:beginning-of-string))))
193196
(if (looking-at "\"\"\"")
194197
;; The last line.
195198
(progn
196199
(goto-char string-beginning-position)
197200
(swift-mode:calculate-indent-of-expression
198201
swift-mode:multiline-statement-offset))
199-
(forward-line -1)
202+
(forward-line 0)
203+
(backward-char)
204+
(swift-mode:goto-non-string-interpolation-bol)
200205
(back-to-indentation)
201206
(if (<= (point) string-beginning-position)
202207
;; The cursor was on the 2nd line of the comment, so aligns with
@@ -212,6 +217,20 @@ declaration and its offset is `swift-mode:basic-offset'."
212217
(swift-mode:calculate-indent-of-multiline-string)
213218
(swift-mode:indentation (point) 0))))))
214219

220+
(defun swift-mode:goto-non-string-interpolation-bol ()
221+
"Back to the beginning of line that is not inside a string interpolation."
222+
(let ((string-beginning-position (nth 8 (syntax-ppss)))
223+
(matching-parenthesis t))
224+
(while (and matching-parenthesis
225+
(< (line-beginning-position) string-beginning-position))
226+
(setq matching-parenthesis
227+
(get-text-property
228+
string-beginning-position 'swift-mode:matching-parenthesis))
229+
(when matching-parenthesis
230+
(goto-char matching-parenthesis)
231+
(setq string-beginning-position (nth 8 (syntax-ppss)))))
232+
(forward-line 0)))
233+
215234
(defun swift-mode:calculate-indent-of-code ()
216235
"Return the indentation of the current line outside multiline comments."
217236
(back-to-indentation)
@@ -222,7 +241,7 @@ declaration and its offset is `swift-mode:basic-offset'."
222241
(next-type (swift-mode:token:type next-token))
223242
(next-text (swift-mode:token:text next-token))
224243
(next-is-on-same-line
225-
(<= (swift-mode:token:end next-token) (line-end-position))))
244+
(<= (swift-mode:token:start next-token) (line-end-position))))
226245
(cond
227246
;; Beginning of the buffer
228247
((eq previous-type 'outside-of-buffer)
@@ -240,6 +259,16 @@ declaration and its offset is `swift-mode:basic-offset'."
240259
(backward-list)
241260
(swift-mode:calculate-indent-of-expression 0))
242261

262+
;; Before end of a string interpolation on the same line
263+
((and next-is-on-same-line
264+
(eq next-type 'string-chunk-after-interpolation))
265+
(goto-char (get-text-property
266+
(swift-mode:token:start next-token)
267+
'swift-mode:matching-parenthesis))
268+
(forward-char 2)
269+
(swift-mode:backward-string-chunk)
270+
(swift-mode:calculate-indent-after-beginning-of-string-interpolation 0))
271+
243272
;; Before , on the same line
244273
((and next-is-on-same-line (eq next-type '\,))
245274
(swift-mode:calculate-indent-of-prefix-comma))
@@ -345,6 +374,12 @@ declaration and its offset is `swift-mode:basic-offset'."
345374
swift-mode:parenthesized-expression-offset
346375
swift-mode:parenthesized-expression-offset))
347376

377+
;; After beginning of a string interpolation
378+
((eq previous-type 'string-chunk-before-interpolation)
379+
(goto-char (swift-mode:token:start previous-token))
380+
(swift-mode:calculate-indent-after-beginning-of-string-interpolation
381+
swift-mode:parenthesized-expression-offset))
382+
348383
;; Before "in" on the same line
349384
((and next-is-on-same-line (equal next-text "in"))
350385
;; When it is for-in statement, align with the token after "for":
@@ -934,7 +969,8 @@ This is also known as Utrecht-style in the Haskell community."
934969
"Return indentation after comma.
935970
936971
Assuming the cursor is on the comma."
937-
(swift-mode:align-with-next-token (swift-mode:find-parent-of-list-element nil)))
972+
(swift-mode:align-with-next-token
973+
(swift-mode:find-parent-of-list-element nil)))
938974

939975
(defun swift-mode:find-parent-of-list-element (&optional utrecht-sytle)
940976
"Move point backward to the parent token of the comma under the cursor.
@@ -1149,6 +1185,19 @@ comma at eol."
11491185
(t
11501186
parent))))
11511187

1188+
(defun swift-mode:calculate-indent-after-beginning-of-string-interpolation
1189+
(offset)
1190+
"Return indentation with OFFSET after the beginning of a string interpolation.
1191+
1192+
Assuming the cursor is before the string chunk."
1193+
(let ((pos (point)))
1194+
(swift-mode:forward-string-chunk)
1195+
(if (< pos (line-beginning-position))
1196+
(progn
1197+
(back-to-indentation)
1198+
(swift-mode:indentation (point) offset))
1199+
(goto-char pos)
1200+
(swift-mode:calculate-indent-of-expression offset offset))))
11521201

11531202
(defun swift-mode:backward-sexps-until (token-types
11541203
&optional
@@ -1531,9 +1580,9 @@ See `indent-new-comment-line' for SOFT."
15311580

15321581
(defun swift-mode:post-self-insert ()
15331582
"Miscellaneous logic for electric indentation."
1534-
;; Indents electrically and insert a space when "*" is inserted at the
1535-
;; beginning of a line inside a multiline comment.
15361583
(cond
1584+
;; Indents electrically and insert a space when "*" is inserted at the
1585+
;; beginning of a line inside a multiline comment.
15371586
((and
15381587
(= last-command-event ?*)
15391588
(nth 4 (syntax-ppss))
@@ -1556,7 +1605,14 @@ See `indent-new-comment-line' for SOFT."
15561605
(swift-mode:incomplete-comment-p)))))
15571606
(backward-char)
15581607
(delete-horizontal-space)
1559-
(forward-char))))
1608+
(forward-char))
1609+
1610+
;; Indents electrically when ")" is inserted at bol as the end of a string
1611+
;; interpolation.
1612+
((and
1613+
(= last-command-event ?\))
1614+
(save-excursion (backward-char) (skip-syntax-backward " ") (bolp)))
1615+
(indent-according-to-mode))))
15601616

15611617
(defun swift-mode:highlight-anchor (indentation)
15621618
"Highlight the anchor point of the INDENTATION."

0 commit comments

Comments
 (0)