@@ -229,10 +229,12 @@ Intended for `syntax-propertize-function'."
229
229
(let* ((chunk (swift-mode:chunk-after (syntax-ppss start))))
230
230
(cond
231
231
((swift-mode:chunk:multiline-string-p chunk)
232
- (swift-mode:syntax-propertize:end-of-multiline-string end))
232
+ (swift-mode:syntax-propertize:end-of-string
233
+ end " \"\"\" " (swift-mode:chunk:pound-count chunk)))
233
234
234
235
((swift-mode:chunk:single-line-string-p chunk)
235
- (swift-mode:syntax-propertize:end-of-single-line-string end))
236
+ (swift-mode:syntax-propertize:end-of-string
237
+ end " \" " (swift-mode:chunk:pound-count chunk)))
236
238
237
239
((swift-mode:chunk:comment-p chunk)
238
240
(goto-char (swift-mode:chunk:start chunk))
@@ -255,21 +257,21 @@ stops where the level becomes zero."
255
257
(< (point ) end)
256
258
(search-forward-regexp pattern end t ))
257
259
(cond
258
- ((equal " \"\"\" " (match-string-no-properties 0 ))
259
- (put-text-property (match-beginning 0 ) (1+ (match-beginning 0 ))
260
+ ((member (match-string-no-properties 0 ) '(" \"\"\" " " \" " ))
261
+ (let ((start (match-beginning 0 ))
262
+ (pound-count 0 )
263
+ (quotation (match-string-no-properties 0 )))
264
+ (save-excursion
265
+ (goto-char start)
266
+ (skip-chars-backward " #" )
267
+ (setq pound-count (- start (point )))
268
+ (setq start (point )))
269
+ (put-text-property start (1+ start)
260
270
'syntax-table
261
271
(string-to-syntax " |" ))
262
- (let ((start (match-beginning 0 )))
263
- (swift-mode:syntax-propertize:end-of-multiline-string end)
264
- (put-text-property start (point ) 'syntax-multiline t )))
265
-
266
- ((equal " \" " (match-string-no-properties 0 ))
267
- (put-text-property (match-beginning 0 ) (1+ (match-beginning 0 ))
268
- 'syntax-table
269
- (string-to-syntax " |" ))
270
- (let ((start (match-beginning 0 )))
271
- (swift-mode:syntax-propertize:end-of-single-line-string end)
272
- (put-text-property start (point ) 'syntax-multiline t )))
272
+ (swift-mode:syntax-propertize:end-of-string
273
+ end quotation pound-count)
274
+ (put-text-property start (point ) 'syntax-multiline t )))
273
275
274
276
((equal " //" (match-string-no-properties 0 ))
275
277
(goto-char (match-beginning 0 ))
@@ -292,71 +294,84 @@ stops where the level becomes zero."
292
294
(goto-char end))
293
295
found-matching-parenthesis))
294
296
295
- (defun swift-mode:syntax-propertize:end-of-multiline-string (end )
296
- " Move point to the end of multiline string.
297
- Assuming the cursor is on a multiline string.
298
- If the end of the string found, put a text property on it.
299
- If the string go beyond END, stop there."
300
- (swift-mode:syntax-propertize:end-of-string end " \"\"\" " ))
301
-
302
- (defun swift-mode:syntax-propertize:end-of-single-line-string (end )
303
- " Move point to the end of single-line string.
304
- Assuming the cursor is on a single-line string.
305
- If the string go beyond END, stop there."
306
- (swift-mode:syntax-propertize:end-of-string end " \" " ))
307
-
308
- (defun swift-mode:syntax-propertize:end-of-string (end quotation )
297
+ (defun swift-mode:syntax-propertize:end-of-string (end quotation pound-count )
309
298
" Move point to the end of single-line/multiline string.
299
+
310
300
Assuming the cursor is on a string.
311
301
If the string go beyond END, stop there.
312
- The string should be terminated with QUOTATION."
302
+ The string should be terminated with QUOTATION, followed by POUND-COUNT of
303
+ pound signs."
313
304
(if (and
314
305
(< (point ) end)
315
306
(search-forward-regexp (concat (regexp-quote quotation) " \\ |(" ) end t ))
316
307
(cond
317
308
((and (equal quotation (match-string-no-properties 0 ))
318
- (not (swift-mode:escaped-p (match-beginning 0 ))))
309
+ (not (swift-mode:escaped-p (match-beginning 0 ) pound-count))
310
+ (progn
311
+ (skip-chars-forward " #" (min end (+ (point ) pound-count)))
312
+ (= (- (point ) (match-end 0 )) pound-count)))
319
313
(put-text-property (1- (point )) (point )
320
314
'syntax-table
321
315
(string-to-syntax " |" )))
322
316
((and (equal " (" (match-string-no-properties 0 ))
323
- (swift-mode:escaped-p (match-beginning 0 )))
317
+ (swift-mode:escaped-p (match-beginning 0 ) pound-count ))
324
318
; ; Found an interpolated expression. Skips the expression.
325
319
; ; We cannot use `scan-sexps' because multiline strings are not yet
326
320
; ; propertized.
327
- (let ((start (- (point ) 2 )))
321
+ (let ((pos-after-open-paren (point ))
322
+ (start
323
+ (save-excursion
324
+ (backward-char ) ; ; (
325
+ (skip-chars-backward " #" )
326
+ (backward-char ) ; ; \
327
+ (point ))))
328
+ ; ; Declares the backslash is not a escape-syntax characters.
328
329
(put-text-property start (1+ start)
329
330
'syntax-table
330
331
(string-to-syntax " w" ))
331
- (put-text-property (1+ start) (+ 2 start)
332
+ ; ; Declares the open parentheses is a generic string delimiter.
333
+ (put-text-property (1- pos-after-open-paren) pos-after-open-paren
332
334
'syntax-table
333
335
(string-to-syntax " |" ))
334
336
(when (swift-mode:syntax-propertize:scan end 1 )
335
337
; ; Found the matching parenthesis. Going further.
338
+ ; ; Declares the close parentheses is a generic string delimiter.
336
339
(put-text-property (1- (point )) (point )
337
340
'syntax-table
338
341
(string-to-syntax " |" ))
342
+ ; ; Records the positions.
339
343
(put-text-property (1- (point )) (point )
340
344
'swift-mode:matching-parenthesis
341
345
start)
342
- (put-text-property start ( + 2 start)
346
+ (put-text-property start pos-after-open-paren
343
347
'swift-mode:matching-parenthesis
344
348
(1- (point )))
345
- (swift-mode:syntax-propertize:end-of-string end quotation))))
349
+ (swift-mode:syntax-propertize:end-of-string
350
+ end quotation pound-count))))
346
351
(t
347
- (swift-mode:syntax-propertize:end-of-string end quotation)))
352
+ (swift-mode:syntax-propertize:end-of-string end quotation pound-count )))
348
353
(goto-char end)))
349
354
350
355
351
- (defun swift-mode:escaped-p (position )
352
- " Return t if the POSITION is proceeded by odd number of backslashes.
353
- Return nil otherwise."
356
+ (defun swift-mode:escaped-p (position pound-count )
357
+ " Return t if the POSITION in a string is escaped.
358
+
359
+ A position is escaped if it is proceeded by POUND-COUNT or more of pound signs
360
+ and odd number of backslashes.
361
+ Return nil otherwise." ; ; FIXME pound-count
354
362
(let ((p position)
355
- (count 0 ))
356
- (while (eq (char-before p) ?\\ )
357
- (setq count (1+ count))
363
+ (backslash-count 0 ))
364
+ (while (eq (char-before p) ?# )
358
365
(setq p (1- p)))
359
- (= (mod count 2 ) 1 )))
366
+ (and
367
+ ; ; While it is a syntax error to have extra pound signs, we allow them
368
+ ; ; here to prevent corruption.
369
+ (<= pound-count (- position p))
370
+ (progn
371
+ (while (eq (char-before p) ?\\ )
372
+ (setq backslash-count (1+ backslash-count))
373
+ (setq p (1- p)))
374
+ (= (mod backslash-count 2 ) 1 )))))
360
375
361
376
; ;; Lexers
362
377
@@ -911,8 +926,9 @@ This function does not return `implicit-;' or `type-:'."
911
926
(point ))))
912
927
913
928
; ; String
914
- ((eq ( char-after ) ?\ " )
929
+ ((looking-at " #* \" " )
915
930
(let ((pos-after-comment (point )))
931
+ (skip-chars-forward " #" )
916
932
(forward-char )
917
933
(swift-mode:end-of-string)
918
934
(swift-mode:token
@@ -1160,8 +1176,11 @@ This function does not return `implicit-;' or `type-:'."
1160
1176
pos-before-comment)))
1161
1177
1162
1178
; ; String
1163
- ((eq (char-before ) ?\" )
1179
+ ((save-excursion
1180
+ (skip-chars-backward " #" )
1181
+ (eq (char-before ) ?\" ))
1164
1182
(let ((pos-before-comment (point )))
1183
+ (skip-chars-backward " #" )
1165
1184
(backward-char )
1166
1185
(swift-mode:beginning-of-string)
1167
1186
(swift-mode:token
@@ -1325,6 +1344,14 @@ If this line ends with a single-line comment, goto just before the comment."
1325
1344
" Return non-nil if the CHUNK is a multiline string."
1326
1345
(eq (swift-mode:chunk:type chunk) 'multiline-string ))
1327
1346
1347
+ (defun swift-mode:chunk:pound-count (chunk )
1348
+ " Return the number of pound signs before the start position of the CHUNK."
1349
+ (save-excursion
1350
+ (goto-char (swift-mode:chunk:start chunk))
1351
+ (swift-mode:beginning-of-string)
1352
+ (skip-chars-backward " #" )
1353
+ (- (swift-mode:chunk:start chunk) (point ))))
1354
+
1328
1355
(defun swift-mode:chunk-after (&optional parser-state )
1329
1356
" Return the chunk at the cursor.
1330
1357
@@ -1342,7 +1369,7 @@ If PARSER-STATE is given, it is used instead of (syntax-ppss)."
1342
1369
; ; string delimiters. So (nth 3 parser-state) may be t even for
1343
1370
; ; single-line string delimiters.
1344
1371
(if (save-excursion (goto-char (nth 8 parser-state))
1345
- (looking-at " \"\"\" " ))
1372
+ (looking-at " #* \"\"\" " ))
1346
1373
(swift-mode:chunk 'multiline-string (nth 8 parser-state))
1347
1374
(swift-mode:chunk 'single-line-string (nth 8 parser-state))))
1348
1375
((eq (nth 4 parser-state) t )
0 commit comments