diff options
| author | Alan Mackenzie | 2019-04-25 18:00:15 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2019-04-25 18:00:15 +0000 |
| commit | 0c2d921a75375e5667224bfd92b28be3b77977b3 (patch) | |
| tree | 6d897212bd8844da18d2b2937fb6cbc5d18550e9 | |
| parent | 6d8e0fc5aa7673540486af9ecbfc0a3e23c305cf (diff) | |
| download | emacs-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.el | 25 | ||||
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 18 | ||||
| -rw-r--r-- | lisp/progmodes/cc-fonts.el | 7 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 28 |
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 | ||