Commit 0c2d921a authored by Alan Mackenzie's avatar Alan Mackenzie

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.
parent 6d8e0fc5
Pipeline #1457 failed with stage
in 50 minutes and 34 seconds
......@@ -503,6 +503,31 @@ to it is returned. This function does not modify the point or the mark."
;; Emacs <22 + XEmacs
'(default-value 'sentence-end)))
(defconst c-c++-raw-string-opener-re "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
;; Matches a C++ raw string opener. Submatch 1 is its identifier.
(defconst c-c++-raw-string-opener-1-re "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
;; Matches a C++ raw string opener starting after the initial R.
(defmacro c-sub-at-c++-raw-string-opener ()
`(save-excursion
(and
(if (eq (char-after) ?R)
(progn (forward-char) t)
(eq (char-before) ?R))
(looking-at c-c++-raw-string-opener-1-re))))
(defmacro c-at-c++-raw-string-opener (&optional pos)
;; Return non-nil if POS (default point) is either at the start of a C++ raw
;; string opener, or after the introductory R of one. The match data is
;; overwritten. On success the opener's identifier will be (match-string
;; 1). Text properties on any characters are ignored.
(if pos
`(save-excursion
(goto-char ,pos)
(c-sub-at-c++-raw-string-opener))
`(c-sub-at-c++-raw-string-opener)))
;; The following is essentially `save-buffer-state' from lazy-lock.el.
;; It ought to be a standard macro.
(defmacro c-save-buffer-state (varlist &rest body)
......
......@@ -6607,15 +6607,14 @@ comment at the start of cc-engine.el for more info."
(while
(and
(search-forward-regexp
"R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)("
c-c++-raw-string-opener-re
(1+ here) 'limit)
(< (point) here)))
(and (eq (point) (1+ here))
(match-beginning 1)
(goto-char (1- (match-beginning 1)))))))
(not (bobp)))))
(eq (char-before) ?R)
(looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)("))
(c-at-c++-raw-string-opener))
(setq open-quote-pos (point)
open-paren-pos (match-end 1)
id (match-string-no-properties 1))
......@@ -6733,7 +6732,7 @@ comment at the start of cc-engine.el for more info."
(concat "\\(" ; 1
c-anchored-cpp-prefix ; 2
"\\)\\|\\(" ; 3
"R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" ; 4
c-c++-raw-string-opener-re ; 4
"\\)")
finish t))
(when (save-excursion
......@@ -6752,7 +6751,7 @@ comment at the start of cc-engine.el for more info."
(goto-char (match-end 2)) ; after the "#".
(while (and (< (point) eom)
(c-syntactic-re-search-forward
"R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" eom t))
c-c++-raw-string-opener-re eom t))
(c-depropertize-raw-string
(match-string-no-properties 1) ; id
(1+ (match-beginning 0)) ; open quote
......@@ -6931,8 +6930,7 @@ comment at the start of cc-engine.el for more info."
(goto-char end)
(setq eoll (c-point 'eoll))
(when (and (null c-old-END-literality)
(search-forward-regexp "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)("
eoll t))
(search-forward-regexp c-c++-raw-string-opener-re eoll t))
(setq state (c-state-semi-pp-to-literal end))
(when (eq (cadr state) 'string)
(unwind-protect
......@@ -6969,7 +6967,7 @@ comment at the start of cc-engine.el for more info."
(while
(and
(setq found
(search-forward-regexp "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)("
(search-forward-regexp c-c++-raw-string-opener-re
c-new-END 'bound))
(<= (match-end 0) beg)))
(when (and found (<= (match-beginning 0) end))
......@@ -6983,7 +6981,7 @@ comment at the start of cc-engine.el for more info."
'syntax-table)
'(1)))
(goto-char (1- (cadr c-old-beg-rs)))
(unless (looking-at "R\"[^ ()\\\n\r\t]\\{0,16\\}(")
(unless (looking-at c-c++-raw-string-opener-re)
(c-clear-char-property (1+ (point)) 'syntax-table)
(c-truncate-semi-nonlit-pos-cache (1+ (point)))
(if (c-search-forward-char-property 'syntax-table '(15)
......@@ -6998,7 +6996,7 @@ comment at the start of cc-engine.el for more info."
(and c-old-beg-rs
(eq (car c-old-beg-rs) 'open-delim)))
(goto-char (cadr c-old-beg-rs))
(when (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
(when (looking-at c-c++-raw-string-opener-1-re)
(setq id (match-string-no-properties 1))
(when (re-search-forward (concat ")" id "\"") nil t) ; No bound.
(setq c-new-END (point-max))
......
......@@ -1684,11 +1684,8 @@ casts and declarations are fontified. Used on level 2 and higher."
(string-start (and (eq (cadr state) 'string)
(car (cddr state))))
(raw-id (and string-start
(save-excursion
(goto-char string-start)
(and (eq (char-before) ?R)
(looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
(match-string-no-properties 1)))))
(c-at-c++-raw-string-opener string-start)
(match-string-no-properties 1)))
(content-start (and raw-id (point))))
;; We go round the next loop twice per raw string, once for each "end".
(while (< (point) limit)
......
......@@ -1261,7 +1261,8 @@ Note that the style variables are always made local to the buffer."
(memq (char-after) c-string-delims)) ; Ignore an unterminated raw string's (.
;; Opening " on last line of text (without EOL).
(c-clear-char-property (point) 'syntax-table)
(c-truncate-semi-nonlit-pos-cache (point)))))
(c-truncate-semi-nonlit-pos-cache (point))
(setq c-new-BEG (min c-new-BEG (point))))))
(t (goto-char end) ; point-max
(when
......@@ -1271,17 +1272,24 @@ Note that the style variables are always made local to the buffer."
(c-clear-char-property (point) 'syntax-table)
(c-truncate-semi-nonlit-pos-cache (point)))))
(unless (and c-multiline-string-start-char
(not (c-characterp c-multiline-string-start-char)))
(unless
(or (and
;; Don't set c-new-BEG/END if we're in a raw string.
(eq beg-literal-type 'string)
(c-at-c++-raw-string-opener (car beg-limits)))
(and c-multiline-string-start-char
(not (c-characterp c-multiline-string-start-char))))
(when (and (eq end-literal-type 'string)
(not (eq (char-before (cdr end-limits)) ?\()))
(c-clear-char-property (1- (cdr end-limits)) 'syntax-table)
(c-truncate-semi-nonlit-pos-cache (1- (cdr end-limits))))
(c-truncate-semi-nonlit-pos-cache (1- (cdr end-limits)))
(setq c-new-END (max c-new-END (cdr end-limits))))
(when (and (eq beg-literal-type 'string)
(memq (char-after (car beg-limits)) c-string-delims))
(c-clear-char-property (car beg-limits) 'syntax-table)
(c-truncate-semi-nonlit-pos-cache (car beg-limits))))))
(c-truncate-semi-nonlit-pos-cache (car beg-limits))
(setq c-new-BEG (min c-new-BEG (car beg-limits)))))))
(defun c-after-change-mark-abnormal-strings (beg end _old-len)
;; 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."
(car beg-limits))
(t ; comment
(cdr beg-limits))))
;; Handle one string each time around the next while loop.
(while
(and
(< (point) c-new-END)
......@@ -1373,10 +1382,15 @@ Note that the style variables are always made local to the buffer."
(cond
((memq (char-after (match-end 0)) '(?\n ?\r))
(c-put-char-property (1- (point)) 'syntax-table '(15))
(c-put-char-property (match-end 0) 'syntax-table '(15)))
(c-put-char-property (match-end 0) 'syntax-table '(15))
(setq c-new-BEG (min c-new-BEG (point))
c-new-END (max c-new-END (match-end 0))))
((or (eq (match-end 0) (point-max))
(eq (char-after (match-end 0)) ?\\)) ; \ at EOB
(c-put-char-property (1- (point)) 'syntax-table '(15))))
(c-put-char-property (1- (point)) 'syntax-table '(15))
(setq c-new-BEG (min c-new-BEG (point))
c-new-END (max c-new-END (match-end 0))) ; Do we need c-new-END?
))
(goto-char (min (1+ (match-end 0)) (point-max))))
(setq s nil)))))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment