summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2019-04-25 15:18:12 +0000
committerAlan Mackenzie <acm@muc.de>2019-04-25 15:18:12 +0000
commitefb8921a574437aed6209695891c14860bd55f51 (patch)
tree58310e515e725caa17f7cd2cc9e3ac1b48bbafde
parenta1386fa6a7698c04902354cd5fefb39056b0a901 (diff)
downloademacs-efb8921a574437aed6209695891c14860bd55f51.tar.gz
Fix some corner cases in the recognition of C++ raw strings.
These are where changing the identifier in a raw string delimiter causes different delimiters to match eachother. * lisp/progmodes/cc-engine.el (c-raw-string-end-delim-disrupted): New variable. (c-before-change-check-raw-strings): Use new variable. (c-after-change-unmark-raw-strings): When typing into an opening delimiter or altering its close delimiter causes the opening delimiter to match a later closing delimiter, clear all syntax-table char properties from the opening delimiter onwards, and set c-new-END to point max. Also, when changing a closing delimiter, check whether its new value matches a previously open opening delimiter earlier in the buffer, and amend the syntax-table text properties appropriately.
-rw-r--r--lisp/progmodes/cc-engine.el82
1 files changed, 42 insertions, 40 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 80115fb3a35..6b44aae0884 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6567,6 +6567,9 @@ comment at the start of cc-engine.el for more info."
;; BEG and END.
(defvar c-old-beg-rs nil)
(defvar c-old-end-rs nil)
+;; Whether a buffer change has disrupted or will disrupt the terminating id of
+;; a raw string.
+(defvar c-raw-string-end-delim-disrupted nil)
(defun c-raw-string-pos ()
;; Get POINT's relationship to any containing raw string.
@@ -6768,17 +6771,12 @@ comment at the start of cc-engine.el for more info."
;; This function is called as a before-change function solely due to its
;; membership of the C++ value of `c-get-state-before-change-functions'.
(goto-char end)
+ (setq c-raw-string-end-delim-disrupted nil)
;; We use the following to detect a R"<id>( being swallowed into a string by
;; the pending change.
(setq c-old-END-literality (c-in-literal))
(c-save-buffer-state
- (;; (beg-rs (progn (goto-char beg) (c-raw-string-pos)))
- ;; (end-rs (progn (goto-char end) (c-raw-string-pos)))
- ; FIXME!!!
- ; Optimize this so that we don't call
- ; `c-raw-string-pos' twice when once
- ; will do. (2016-06-02).
- (term-del (c-raw-string-in-end-delim beg end))
+ ((term-del (c-raw-string-in-end-delim beg end))
Rquote close-quote)
(setq c-old-beg-rs (progn (goto-char beg) (c-raw-string-pos))
c-old-end-rs (progn (goto-char end) (c-raw-string-pos)))
@@ -6792,6 +6790,7 @@ comment at the start of cc-engine.el for more info."
(<= (car term-del) (nth 3 c-old-beg-rs))))
(setq Rquote (1- (cadr c-old-beg-rs))
close-quote (1+ (cdr term-del)))
+ (setq c-raw-string-end-delim-disrupted t)
(c-depropertize-raw-strings-in-region Rquote close-quote)
(setq c-new-BEG (min c-new-BEG Rquote)
c-new-END (max c-new-END close-quote)))
@@ -6991,42 +6990,45 @@ comment at the start of cc-engine.el for more info."
(c-point 'eol))
(c-clear-char-property (1- (point)) 'syntax-table))))
+ ;; Have we matched up with an existing terminator by typing into an
+ ;; opening delimiter? ... or by messing up a raw string's terminator so
+ ;; that it now matches a later terminator?
+ (when
+ (or c-raw-string-end-delim-disrupted
+ (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\\}\\)(")
+ (setq id (match-string-no-properties 1))
+ (when (re-search-forward (concat ")" id "\"") nil t) ; No bound.
+ (setq c-new-END (point-max))
+ (c-clear-char-properties (cadr c-old-beg-rs) c-new-END
+ 'syntax-table)
+ (c-truncate-semi-nonlit-pos-cache (cadr c-old-beg-rs)))))
;; Have we terminated an existing raw string by inserting or removing
;; text?
(when (eq c-old-END-literality 'string)
- (setq state (c-state-semi-pp-to-literal beg))
- (cond
- ;; Possibly terminating a(n un)terminated raw string.
- ((eq (nth 3 (car state)) t)
- (goto-char (nth 8 (car state)))
- (when
- (and (eq (char-after) ?\()
- (search-backward-regexp
- "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)\\=" (- (point) 18) t))
- (setq id (match-string-no-properties 1)
- found-beg (match-beginning 0)
- found-end (1+ (match-end 0)))))
- ;; Possibly terminating an already terminated raw string.
- ((eq (nth 3 (car state)) ?\")
- (goto-char (nth 8 (car state)))
- (when
- (and (eq (char-before) ?R)
- (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)("))
- (setq id (match-string-no-properties 1)
- found-beg (1- (point))
- found-end (match-end 0)))))
- (when id
- (goto-char (max (- beg 18) (point-min)))
- (when (search-forward (concat ")" id "\"") (+ end 1 (length id)) t)
- ;; Has an earlier close delimiter just been inserted into an
- ;; already terminated raw string?
- (if (and (eq (nth 3 (car state)) ?\")
- (search-forward (concat ")" id "\"") nil t))
- (setq found-end (point)))
- (setq c-new-BEG (min c-new-BEG found-beg)
- c-new-END (max c-new-END found-end))
- (c-clear-char-properties found-beg found-end 'syntax-table)
- (c-truncate-semi-nonlit-pos-cache found-beg))))
+ ;; Have we just made or modified a closing delimiter?
+ (goto-char (max (- beg 18) (point-min)))
+ (while
+ (and
+ (setq found
+ (search-forward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\""
+ (+ end 17) t))
+ (< (match-end 0) beg)))
+ (when (and found (<= (match-beginning 0) end))
+ (setq id (match-string-no-properties 1))
+ (goto-char (match-beginning 0))
+ (while
+ (and
+ (setq found (search-backward (concat "R\"" id "(") nil t))
+ (setq state (c-state-semi-pp-to-literal (point)))
+ (memq (nth 3 (car state)) '(t ?\"))))
+ (when found
+ (setq c-new-BEG (min (point) c-new-BEG)
+ c-new-END (point-max))
+ (c-clear-char-properties (point) c-new-END 'syntax-table)
+ (c-truncate-semi-nonlit-pos-cache (point)))))
;; Are there any raw strings in a newly created macro?
(when (< beg end)