@@ -229,10 +229,12 @@ Intended for `syntax-propertize-function'."
229229 (let* ((chunk (swift-mode:chunk-after (syntax-ppss start))))
230230 (cond
231231 ((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)))
233234
234235 ((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)))
236238
237239 ((swift-mode:chunk:comment-p chunk)
238240 (goto-char (swift-mode:chunk:start chunk))
@@ -255,21 +257,21 @@ stops where the level becomes zero."
255257 (< (point ) end)
256258 (search-forward-regexp pattern end t ))
257259 (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)
260270 'syntax-table
261271 (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 )))
273275
274276 ((equal " //" (match-string-no-properties 0 ))
275277 (goto-char (match-beginning 0 ))
@@ -292,71 +294,84 @@ stops where the level becomes zero."
292294 (goto-char end))
293295 found-matching-parenthesis))
294296
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 )
309298 " Move point to the end of single-line/multiline string.
299+
310300Assuming the cursor is on a string.
311301If 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."
313304 (if (and
314305 (< (point ) end)
315306 (search-forward-regexp (concat (regexp-quote quotation) " \\ |(" ) end t ))
316307 (cond
317308 ((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)))
319313 (put-text-property (1- (point )) (point )
320314 'syntax-table
321315 (string-to-syntax " |" )))
322316 ((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 ))
324318 ; ; Found an interpolated expression. Skips the expression.
325319 ; ; We cannot use `scan-sexps' because multiline strings are not yet
326320 ; ; 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.
328329 (put-text-property start (1+ start)
329330 'syntax-table
330331 (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
332334 'syntax-table
333335 (string-to-syntax " |" ))
334336 (when (swift-mode:syntax-propertize:scan end 1 )
335337 ; ; Found the matching parenthesis. Going further.
338+ ; ; Declares the close parentheses is a generic string delimiter.
336339 (put-text-property (1- (point )) (point )
337340 'syntax-table
338341 (string-to-syntax " |" ))
342+ ; ; Records the positions.
339343 (put-text-property (1- (point )) (point )
340344 'swift-mode:matching-parenthesis
341345 start)
342- (put-text-property start ( + 2 start)
346+ (put-text-property start pos-after-open-paren
343347 'swift-mode:matching-parenthesis
344348 (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))))
346351 (t
347- (swift-mode:syntax-propertize:end-of-string end quotation)))
352+ (swift-mode:syntax-propertize:end-of-string end quotation pound-count )))
348353 (goto-char end)))
349354
350355
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
354362 (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) ?# )
358365 (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 )))))
360375
361376; ;; Lexers
362377
@@ -911,8 +926,9 @@ This function does not return `implicit-;' or `type-:'."
911926 (point ))))
912927
913928 ; ; String
914- ((eq ( char-after ) ?\ " )
929+ ((looking-at " #* \" " )
915930 (let ((pos-after-comment (point )))
931+ (skip-chars-forward " #" )
916932 (forward-char )
917933 (swift-mode:end-of-string)
918934 (swift-mode:token
@@ -1160,8 +1176,11 @@ This function does not return `implicit-;' or `type-:'."
11601176 pos-before-comment)))
11611177
11621178 ; ; String
1163- ((eq (char-before ) ?\" )
1179+ ((save-excursion
1180+ (skip-chars-backward " #" )
1181+ (eq (char-before ) ?\" ))
11641182 (let ((pos-before-comment (point )))
1183+ (skip-chars-backward " #" )
11651184 (backward-char )
11661185 (swift-mode:beginning-of-string)
11671186 (swift-mode:token
@@ -1325,6 +1344,14 @@ If this line ends with a single-line comment, goto just before the comment."
13251344 " Return non-nil if the CHUNK is a multiline string."
13261345 (eq (swift-mode:chunk:type chunk) 'multiline-string ))
13271346
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+
13281355(defun swift-mode:chunk-after (&optional parser-state )
13291356 " Return the chunk at the cursor.
13301357
@@ -1342,7 +1369,7 @@ If PARSER-STATE is given, it is used instead of (syntax-ppss)."
13421369 ; ; string delimiters. So (nth 3 parser-state) may be t even for
13431370 ; ; single-line string delimiters.
13441371 (if (save-excursion (goto-char (nth 8 parser-state))
1345- (looking-at " \"\"\" " ))
1372+ (looking-at " #* \"\"\" " ))
13461373 (swift-mode:chunk 'multiline-string (nth 8 parser-state))
13471374 (swift-mode:chunk 'single-line-string (nth 8 parser-state))))
13481375 ((eq (nth 4 parser-state) t )
0 commit comments