aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2019-04-25 18:00:15 +0000
committerAlan Mackenzie2019-04-25 18:00:15 +0000
commit0c2d921a75375e5667224bfd92b28be3b77977b3 (patch)
tree6d897212bd8844da18d2b2937fb6cbc5d18550e9
parent6d8e0fc5aa7673540486af9ecbfc0a3e23c305cf (diff)
downloademacs-0c2d921a75375e5667224bfd92b28be3b77977b3.tar.gz
emacs-0c2d921a75375e5667224bfd92b28be3b77977b3.zip
Restore fontification of delimiters of multiline CC Mode strings.
E.g., on typing the closing delimiter of a string continued onto a second line, the opening delimiter retained its font-lock-warning-face. * lisp/progmodes/cc-defs.el (c-c++-raw-string-opener-re) (c-c++-raw-string-opener-1-re): New constants. (c-sub-at-c++-raw-string-opener, c-at-c++-raw-string-opener): New macros. * lisp/progmodes/cc-engine.el (c-raw-string-pos) (c-depropertize-raw-strings-in-region, c-after-change-unmark-raw-strings): Replace uses of open-coded raw string regexps by the new constants and macros in cc-defs.el. * lisp/progmodes/cc-fonts.el (c-font-lock-raw-strings): Ditto * lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings): Set c-new-BEG to the beginning of the string when we encounter its closing ". When not in a raw string, but in a string, clear syntax-table properties from its delimiters and set c-new-BEG/END to its limits. (c-after-change-mark-abnormal-strings): When applying syntax-table properties to string delimiters, also set c-new-BEG/END to ensure subsequent fontification.
-rw-r--r--lisp/progmodes/cc-defs.el25
-rw-r--r--lisp/progmodes/cc-engine.el18
-rw-r--r--lisp/progmodes/cc-fonts.el7
-rw-r--r--lisp/progmodes/cc-mode.el28
4 files changed, 56 insertions, 22 deletions
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 87ddf3ac1e2..cd4ed6b352e 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -503,6 +503,31 @@ to it is returned. This function does not modify the point or the mark."
503 ;; Emacs <22 + XEmacs 503 ;; Emacs <22 + XEmacs
504 '(default-value 'sentence-end))) 504 '(default-value 'sentence-end)))
505 505
506(defconst c-c++-raw-string-opener-re "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
507;; Matches a C++ raw string opener. Submatch 1 is its identifier.
508
509(defconst c-c++-raw-string-opener-1-re "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
510;; Matches a C++ raw string opener starting after the initial R.
511
512(defmacro c-sub-at-c++-raw-string-opener ()
513 `(save-excursion
514 (and
515 (if (eq (char-after) ?R)
516 (progn (forward-char) t)
517 (eq (char-before) ?R))
518 (looking-at c-c++-raw-string-opener-1-re))))
519
520(defmacro c-at-c++-raw-string-opener (&optional pos)
521 ;; Return non-nil if POS (default point) is either at the start of a C++ raw
522 ;; string opener, or after the introductory R of one. The match data is
523 ;; overwritten. On success the opener's identifier will be (match-string
524 ;; 1). Text properties on any characters are ignored.
525 (if pos
526 `(save-excursion
527 (goto-char ,pos)
528 (c-sub-at-c++-raw-string-opener))
529 `(c-sub-at-c++-raw-string-opener)))
530
506;; The following is essentially `save-buffer-state' from lazy-lock.el. 531;; The following is essentially `save-buffer-state' from lazy-lock.el.
507;; It ought to be a standard macro. 532;; It ought to be a standard macro.
508(defmacro c-save-buffer-state (varlist &rest body) 533(defmacro c-save-buffer-state (varlist &rest body)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 6b44aae0884..242954dbf25 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6607,15 +6607,14 @@ comment at the start of cc-engine.el for more info."
6607 (while 6607 (while
6608 (and 6608 (and
6609 (search-forward-regexp 6609 (search-forward-regexp
6610 "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" 6610 c-c++-raw-string-opener-re
6611 (1+ here) 'limit) 6611 (1+ here) 'limit)
6612 (< (point) here))) 6612 (< (point) here)))
6613 (and (eq (point) (1+ here)) 6613 (and (eq (point) (1+ here))
6614 (match-beginning 1) 6614 (match-beginning 1)
6615 (goto-char (1- (match-beginning 1))))))) 6615 (goto-char (1- (match-beginning 1)))))))
6616 (not (bobp))))) 6616 (not (bobp)))))
6617 (eq (char-before) ?R) 6617 (c-at-c++-raw-string-opener))
6618 (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)("))
6619 (setq open-quote-pos (point) 6618 (setq open-quote-pos (point)
6620 open-paren-pos (match-end 1) 6619 open-paren-pos (match-end 1)
6621 id (match-string-no-properties 1)) 6620 id (match-string-no-properties 1))
@@ -6733,7 +6732,7 @@ comment at the start of cc-engine.el for more info."
6733 (concat "\\(" ; 1 6732 (concat "\\(" ; 1
6734 c-anchored-cpp-prefix ; 2 6733 c-anchored-cpp-prefix ; 2
6735 "\\)\\|\\(" ; 3 6734 "\\)\\|\\(" ; 3
6736 "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" ; 4 6735 c-c++-raw-string-opener-re ; 4
6737 "\\)") 6736 "\\)")
6738 finish t)) 6737 finish t))
6739 (when (save-excursion 6738 (when (save-excursion
@@ -6752,7 +6751,7 @@ comment at the start of cc-engine.el for more info."
6752 (goto-char (match-end 2)) ; after the "#". 6751 (goto-char (match-end 2)) ; after the "#".
6753 (while (and (< (point) eom) 6752 (while (and (< (point) eom)
6754 (c-syntactic-re-search-forward 6753 (c-syntactic-re-search-forward
6755 "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" eom t)) 6754 c-c++-raw-string-opener-re eom t))
6756 (c-depropertize-raw-string 6755 (c-depropertize-raw-string
6757 (match-string-no-properties 1) ; id 6756 (match-string-no-properties 1) ; id
6758 (1+ (match-beginning 0)) ; open quote 6757 (1+ (match-beginning 0)) ; open quote
@@ -6931,8 +6930,7 @@ comment at the start of cc-engine.el for more info."
6931 (goto-char end) 6930 (goto-char end)
6932 (setq eoll (c-point 'eoll)) 6931 (setq eoll (c-point 'eoll))
6933 (when (and (null c-old-END-literality) 6932 (when (and (null c-old-END-literality)
6934 (search-forward-regexp "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" 6933 (search-forward-regexp c-c++-raw-string-opener-re eoll t))
6935 eoll t))
6936 (setq state (c-state-semi-pp-to-literal end)) 6934 (setq state (c-state-semi-pp-to-literal end))
6937 (when (eq (cadr state) 'string) 6935 (when (eq (cadr state) 'string)
6938 (unwind-protect 6936 (unwind-protect
@@ -6969,7 +6967,7 @@ comment at the start of cc-engine.el for more info."
6969 (while 6967 (while
6970 (and 6968 (and
6971 (setq found 6969 (setq found
6972 (search-forward-regexp "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" 6970 (search-forward-regexp c-c++-raw-string-opener-re
6973 c-new-END 'bound)) 6971 c-new-END 'bound))
6974 (<= (match-end 0) beg))) 6972 (<= (match-end 0) beg)))
6975 (when (and found (<= (match-beginning 0) end)) 6973 (when (and found (<= (match-beginning 0) end))
@@ -6983,7 +6981,7 @@ comment at the start of cc-engine.el for more info."
6983 'syntax-table) 6981 'syntax-table)
6984 '(1))) 6982 '(1)))
6985 (goto-char (1- (cadr c-old-beg-rs))) 6983 (goto-char (1- (cadr c-old-beg-rs)))
6986 (unless (looking-at "R\"[^ ()\\\n\r\t]\\{0,16\\}(") 6984 (unless (looking-at c-c++-raw-string-opener-re)
6987 (c-clear-char-property (1+ (point)) 'syntax-table) 6985 (c-clear-char-property (1+ (point)) 'syntax-table)
6988 (c-truncate-semi-nonlit-pos-cache (1+ (point))) 6986 (c-truncate-semi-nonlit-pos-cache (1+ (point)))
6989 (if (c-search-forward-char-property 'syntax-table '(15) 6987 (if (c-search-forward-char-property 'syntax-table '(15)
@@ -6998,7 +6996,7 @@ comment at the start of cc-engine.el for more info."
6998 (and c-old-beg-rs 6996 (and c-old-beg-rs
6999 (eq (car c-old-beg-rs) 'open-delim))) 6997 (eq (car c-old-beg-rs) 'open-delim)))
7000 (goto-char (cadr c-old-beg-rs)) 6998 (goto-char (cadr c-old-beg-rs))
7001 (when (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(") 6999 (when (looking-at c-c++-raw-string-opener-1-re)
7002 (setq id (match-string-no-properties 1)) 7000 (setq id (match-string-no-properties 1))
7003 (when (re-search-forward (concat ")" id "\"") nil t) ; No bound. 7001 (when (re-search-forward (concat ")" id "\"") nil t) ; No bound.
7004 (setq c-new-END (point-max)) 7002 (setq c-new-END (point-max))
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 4a5cf5719be..831fa308866 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1684,11 +1684,8 @@ casts and declarations are fontified. Used on level 2 and higher."
1684 (string-start (and (eq (cadr state) 'string) 1684 (string-start (and (eq (cadr state) 'string)
1685 (car (cddr state)))) 1685 (car (cddr state))))
1686 (raw-id (and string-start 1686 (raw-id (and string-start
1687 (save-excursion 1687 (c-at-c++-raw-string-opener string-start)
1688 (goto-char string-start) 1688 (match-string-no-properties 1)))
1689 (and (eq (char-before) ?R)
1690 (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
1691 (match-string-no-properties 1)))))
1692 (content-start (and raw-id (point)))) 1689 (content-start (and raw-id (point))))
1693 ;; We go round the next loop twice per raw string, once for each "end". 1690 ;; We go round the next loop twice per raw string, once for each "end".
1694 (while (< (point) limit) 1691 (while (< (point) limit)
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 27ed04fea52..1a360048752 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1261,7 +1261,8 @@ Note that the style variables are always made local to the buffer."
1261 (memq (char-after) c-string-delims)) ; Ignore an unterminated raw string's (. 1261 (memq (char-after) c-string-delims)) ; Ignore an unterminated raw string's (.
1262 ;; Opening " on last line of text (without EOL). 1262 ;; Opening " on last line of text (without EOL).
1263 (c-clear-char-property (point) 'syntax-table) 1263 (c-clear-char-property (point) 'syntax-table)
1264 (c-truncate-semi-nonlit-pos-cache (point))))) 1264 (c-truncate-semi-nonlit-pos-cache (point))
1265 (setq c-new-BEG (min c-new-BEG (point))))))
1265 1266
1266 (t (goto-char end) ; point-max 1267 (t (goto-char end) ; point-max
1267 (when 1268 (when
@@ -1271,17 +1272,24 @@ Note that the style variables are always made local to the buffer."
1271 (c-clear-char-property (point) 'syntax-table) 1272 (c-clear-char-property (point) 'syntax-table)
1272 (c-truncate-semi-nonlit-pos-cache (point))))) 1273 (c-truncate-semi-nonlit-pos-cache (point)))))
1273 1274
1274 (unless (and c-multiline-string-start-char 1275 (unless
1275 (not (c-characterp c-multiline-string-start-char))) 1276 (or (and
1277 ;; Don't set c-new-BEG/END if we're in a raw string.
1278 (eq beg-literal-type 'string)
1279 (c-at-c++-raw-string-opener (car beg-limits)))
1280 (and c-multiline-string-start-char
1281 (not (c-characterp c-multiline-string-start-char))))
1276 (when (and (eq end-literal-type 'string) 1282 (when (and (eq end-literal-type 'string)
1277 (not (eq (char-before (cdr end-limits)) ?\())) 1283 (not (eq (char-before (cdr end-limits)) ?\()))
1278 (c-clear-char-property (1- (cdr end-limits)) 'syntax-table) 1284 (c-clear-char-property (1- (cdr end-limits)) 'syntax-table)
1279 (c-truncate-semi-nonlit-pos-cache (1- (cdr end-limits)))) 1285 (c-truncate-semi-nonlit-pos-cache (1- (cdr end-limits)))
1286 (setq c-new-END (max c-new-END (cdr end-limits))))
1280 1287
1281 (when (and (eq beg-literal-type 'string) 1288 (when (and (eq beg-literal-type 'string)
1282 (memq (char-after (car beg-limits)) c-string-delims)) 1289 (memq (char-after (car beg-limits)) c-string-delims))
1283 (c-clear-char-property (car beg-limits) 'syntax-table) 1290 (c-clear-char-property (car beg-limits) 'syntax-table)
1284 (c-truncate-semi-nonlit-pos-cache (car beg-limits)))))) 1291 (c-truncate-semi-nonlit-pos-cache (car beg-limits))
1292 (setq c-new-BEG (min c-new-BEG (car beg-limits)))))))
1285 1293
1286(defun c-after-change-mark-abnormal-strings (beg end _old-len) 1294(defun c-after-change-mark-abnormal-strings (beg end _old-len)
1287 ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with 1295 ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with
@@ -1352,6 +1360,7 @@ Note that the style variables are always made local to the buffer."
1352 (car beg-limits)) 1360 (car beg-limits))
1353 (t ; comment 1361 (t ; comment
1354 (cdr beg-limits)))) 1362 (cdr beg-limits))))
1363 ;; Handle one string each time around the next while loop.
1355 (while 1364 (while
1356 (and 1365 (and
1357 (< (point) c-new-END) 1366 (< (point) c-new-END)
@@ -1373,10 +1382,15 @@ Note that the style variables are always made local to the buffer."
1373 (cond 1382 (cond
1374 ((memq (char-after (match-end 0)) '(?\n ?\r)) 1383 ((memq (char-after (match-end 0)) '(?\n ?\r))
1375 (c-put-char-property (1- (point)) 'syntax-table '(15)) 1384 (c-put-char-property (1- (point)) 'syntax-table '(15))
1376 (c-put-char-property (match-end 0) 'syntax-table '(15))) 1385 (c-put-char-property (match-end 0) 'syntax-table '(15))
1386 (setq c-new-BEG (min c-new-BEG (point))
1387 c-new-END (max c-new-END (match-end 0))))
1377 ((or (eq (match-end 0) (point-max)) 1388 ((or (eq (match-end 0) (point-max))
1378 (eq (char-after (match-end 0)) ?\\)) ; \ at EOB 1389 (eq (char-after (match-end 0)) ?\\)) ; \ at EOB
1379 (c-put-char-property (1- (point)) 'syntax-table '(15)))) 1390 (c-put-char-property (1- (point)) 'syntax-table '(15))
1391 (setq c-new-BEG (min c-new-BEG (point))
1392 c-new-END (max c-new-END (match-end 0))) ; Do we need c-new-END?
1393 ))
1380 (goto-char (min (1+ (match-end 0)) (point-max)))) 1394 (goto-char (min (1+ (match-end 0)) (point-max))))
1381 (setq s nil))))) 1395 (setq s nil)))))
1382 1396