emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master fabb558: Handle C++ raw strings.


From: Alan Mackenzie
Subject: [Emacs-diffs] master fabb558: Handle C++ raw strings.
Date: Thu, 9 Jun 2016 12:27:53 +0000 (UTC)

branch: master
commit fabb558250fca14a2684357a95225241253cdfda
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    Handle C++ raw strings.
    
    * lisp/progmodes/cc-engine.el (c-raw-string-pos, c-depropertize-raw-string)
    (c-depropertize-raw-strings-in-region,
    c-before-change-check-raw-strings)
    (c-propertize-raw-string-opener, c-after-change-re-mark-raw-strings): New
    functions.
    
    * lisp/progmodes/cc-fonts.el (c-basic-matchers-before): Insert a clause for
    c-font-lock-raw-strings.
    (c-font-lock-raw-strings): New function.
    
    * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): Insert
    c-before-change-check-raw-strings into the C++ value, and c-depropertize-CPP
    into the values for C, C++, and Objective C.
    (c-before-font-lock-functions): Insert c-after-change-re-mark-raw-strings 
into
    the C++ value.
    
    * lisp/progmodes/cc-mode.el (c-old-BEG, c-old-END): New variables.
    (c-depropertize-CPP): New function, extracted from
    c-neutralize-syntax-in-and-mark-CPP.
    (c-neutralize-syntax-in-and-mark-CPP): Remove the call to
    c-clear-char-property-with-value for 'syntax-table value '(1) at the 
beginning
    of the function.
    (c-after-change): Set c-old-BEG and c-old-END to the current values of
    c-new-BEG and c-new-END.
---
 lisp/progmodes/cc-engine.el |  338 ++++++++++++++++++++++++++++++++++++++++++-
 lisp/progmodes/cc-fonts.el  |   41 ++++++
 lisp/progmodes/cc-langs.el  |    4 +
 lisp/progmodes/cc-mode.el   |   39 ++++-
 4 files changed, 416 insertions(+), 6 deletions(-)

diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 4d6a120..7c77b70 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -83,8 +83,9 @@
 ;;
 ;; 'syntax-table
 ;;   Used to modify the syntax of some characters.  It is used to
-;;   mark the "<" and ">" of angle bracket parens with paren syntax, and
-;;   to "hide" obtrusive characters in preprocessor lines.
+;;   mark the "<" and ">" of angle bracket parens with paren syntax, to
+;;   "hide" obtrusive characters in preprocessor lines, and to mark C++
+;;   raw strings to enable their fontification.
 ;;
 ;;   This property is used on single characters and is therefore
 ;;   always treated as front and rear nonsticky (or start and end open
@@ -2293,7 +2294,8 @@ comment at the start of cc-engine.el for more info."
   ;;     (STATE TYPE (BEG . END))     if TO is in a literal; or
   ;;     (STATE)                      otherwise,
   ;; where STATE is the parsing state at TO, TYPE is the type of the literal
-  ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the 
literal.
+  ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the 
literal,
+  ;; including the delimiters.
   ;;
   ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character
   ;; comment opener, this is recognized as being in a comment literal.
@@ -5657,6 +5659,9 @@ comment at the start of cc-engine.el for more info."
 ;; Set by c-common-init in cc-mode.el.
 (defvar c-new-BEG)
 (defvar c-new-END)
+;; Set by c-after-change in cc-mode.el.
+(defvar c-old-BEG)
+(defvar c-old-END)
 
 (defun c-before-change-check-<>-operators (beg end)
   ;; Unmark certain pairs of "< .... >" which are currently marked as
@@ -5777,6 +5782,333 @@ comment at the start of cc-engine.el for more info."
                                       'c-decl-arg-start)))))))
       (or (c-forward-<>-arglist nil)
          (forward-char)))))
+
+
+;; Functions to handle C++ raw strings.
+;;
+;; A valid C++ raw string looks like
+;;     R"<id>(<contents>)<id>"
+;; , where <id> is an identifier from 0 to 16 characters long, not containing
+;; spaces, control characters, double quote or left/right paren.  <contents>
+;; can include anything which isn't the terminating )<id>", including new
+;; lines, "s, parentheses, etc.
+;;
+;; CC Mode handles C++ raw strings by the use of `syntax-table' text
+;; properties as follows:
+;;
+;; (i) On a validly terminated raw string, no `syntax-table' text properties
+;;   are applied to the opening and closing delimiters, but any " in the
+;;   contents is given the property value "punctuation" (`(1)') to prevent it
+;;   interacting with the "s in the delimiters.
+;;
+;;   The font locking routine `c-font-lock-c++-raw-strings' (in cc-fonts.el)
+;;   recognizes valid raw strings, and fontifies the delimiters (apart from
+;;   the parentheses) with the default face and the parentheses and the
+;;   <contents> with font-lock-string-face.
+;;
+;; (ii) A valid, but unterminated, raw string opening delimiter gets the
+;;   "punctuation" value (`(1)') of the `syntax-table' text property, and the
+;;   open parenthesis gets the "string fence" value (`(15)').
+;;
+;;   `c-font-lock-c++-raw-strings' puts c-font-lock-warning-face on the entire
+;;   unmatched opening delimiter (from the R up to the open paren), and allows
+;;   the rest of the buffer to get font-lock-string-face, caused by the
+;;   unmatched "string fence" `syntax-table' text property value.
+;;
+;; (iii) Inside a macro, a valid raw string is handled as in (i).  An
+;;   unmatched opening delimiter is handled slightly differently.  In addition
+;;   to the "punctuation" and "string fence" properties on the delimiter,
+;;   another "string fence" `syntax-table' property is applied to the last
+;;   possible character of the macro before the terminating linefeed (if there
+;;   is such a character after the "(").  This "last possible" character is
+;;   never a backslash escaping the end of line.  If the character preceding
+;;   this "last possible" character is itself a backslash, this preceding
+;;   character gets a "punctuation" `syntax-table' value.  If the "(" is
+;;   already at the end of the macro, it gets the "punctuaion" value, and no
+;;   "string fence"s are used.
+;;
+;;   The effect on the fontification of either of these tactics is that rest of
+;;   the macro (if any) after the "(" gets font-lock-string-face, but the rest
+;;   of the file is fontified normally.
+
+
+(defun c-raw-string-pos ()
+  ;; Get POINT's relationship to any containing raw string.
+  ;; If point isn't in a raw string, return nil.
+  ;; Otherwise, return the following list:
+  ;;
+  ;;   (POS B\" B\( E\) E\")
+  ;;
+  ;; , where POS is the symbol `open-delim' if point is in the opening
+  ;; delimiter, the symbol `close-delim' if it's in the closing delimiter, and
+  ;; nil if it's in the string body.  B\", B\(, E\), E\" are the positions of
+  ;; the opening and closing quotes and parentheses of a correctly terminated
+  ;; raw string.  (N.B.: E\) and E\" are NOT on the "outside" of these
+  ;; characters.)  If the raw string is not terminated, E\) and E\" are set to
+  ;; nil.
+  ;;
+  ;; Note: this routine is dependant upon the correct syntax-table text
+  ;; properties being set.
+  (let* ((safe (c-state-semi-safe-place (point)))
+        (state (c-state-pp-to-literal safe (point)))
+        open-quote-pos open-paren-pos close-paren-pos close-quote-pos id)
+    (save-excursion
+      (when
+         (and
+          (cond
+           ((null (cadr state))
+            (or (eq (char-after) ?\")
+                (search-backward "\"" (max (- (point) 17) (point-min)) t)))
+           ((and (eq (cadr state) 'string)
+                 (goto-char (car (nth 2 state)))
+                 (or (eq (char-after) ?\")
+                     (search-backward "\"" (max (- (point) 17) (point-min)) t))
+                 (not (bobp)))))
+          (eq (char-before) ?R)
+          (looking-at "\"\\([^ ()\\\n\r\t]\\{,16\\}\\)("))
+       (setq open-quote-pos (point)
+             open-paren-pos (match-end 1)
+             id (match-string-no-properties 1))
+       (goto-char (1+ open-paren-pos))
+       (when (and (not (c-get-char-property open-paren-pos 'syntax-table))
+                  (search-forward (concat ")" id "\"") nil t))
+         (setq close-paren-pos (match-beginning 0)
+               close-quote-pos (1- (point))))))
+    (and open-quote-pos
+        (list
+         (cond
+          ((<= (point) open-paren-pos)
+           'open-delim)
+          ((and close-paren-pos
+                (> (point) close-paren-pos))
+           'close-delim)
+          (t nil))
+         open-quote-pos open-paren-pos close-paren-pos close-quote-pos))))
+
+(defun c-depropertize-raw-string (id open-quote open-paren bound)
+  ;; Point is immediately after a raw string opening delimiter.  Remove any
+  ;; `syntax-table' text properties associated with the delimiter (if it's
+  ;; unmatched) or the raw string.
+  ;;
+  ;; ID, a string, is the delimiter's identifier.  OPEN-QUOTE and OPEN-PAREN
+  ;; are the buffer positions of the delimiter's components.  BOUND is the
+  ;; bound for searching for a matching closing delimiter; it is usually nil,
+  ;; but if we're inside a macro, it's the end of the macro.
+  ;;
+  ;; Point is moved to after the (terminated) raw string, or left after the
+  ;; unmatched opening delimiter, as the case may be.  The return value is of
+  ;; no significance.
+  (let ((open-paren-prop (c-get-char-property open-paren 'syntax-table)))
+    (cond
+     ((null open-paren-prop)
+      ;; A terminated raw string
+      (if (search-forward (concat ")" id "\"") nil t)
+         (c-clear-char-property-with-value
+          (1+ open-paren) (match-beginning 0) 'syntax-table '(1))))
+     ((or (and (equal open-paren-prop '(15)) (null bound))
+         (equal open-paren-prop '(1)))
+      ;; An unterminated raw string either not in a macro, or in a macro with
+      ;; the open parenthesis right up against the end of macro
+      (c-clear-char-property open-quote 'syntax-table)
+      (c-clear-char-property open-paren 'syntax-table))
+     (t
+      ;; An unterminated string in a macro, with at least one char after the
+      ;; open paren
+      (c-clear-char-property open-quote 'syntax-table)
+      (c-clear-char-property open-paren 'syntax-table)
+      (let ((after-string-fence-pos
+            (save-excursion
+              (goto-char (1+ open-paren))
+              (c-search-forward-char-property 'syntax-table '(15) bound))))
+       (when after-string-fence-pos
+         (c-clear-char-property (1- after-string-fence-pos) 'syntax-table)))
+      ))))
+
+(defun c-depropertize-raw-strings-in-region (start finish)
+  ;; Remove any `syntax-table' text properties associated with C++ raw strings
+  ;; contained in the region (START FINISH).  Point is undefined at entry and
+  ;; exit, and the return value has no significance.
+  (goto-char start)
+  (while (and (< (point) finish)
+             (re-search-forward
+              (concat "\\("                                 ; 1
+                      c-anchored-cpp-prefix                 ; 2
+                      "\\)\\|\\("                           ; 3
+                      "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)("   ; 4
+                      "\\)")
+              finish t))
+    (when (save-excursion
+           (goto-char (match-beginning 0)) (not (c-in-literal)))
+      (if (match-beginning 4)          ; the id
+         ;; We've found a raw string
+         (c-depropertize-raw-string
+          (match-string-no-properties 4) ; id
+          (1+ (match-beginning 3))       ; open quote
+          (match-end 4)                  ; open paren
+          nil)                           ; bound
+       ;; We've found a CPP construct.  Search for raw strings within it.
+       (goto-char (match-beginning 2)) ; the "#"
+       (c-end-of-macro)
+       (let ((eom (point)))
+         (goto-char (match-end 2))     ; after the "#".
+         (while (and (< (point) eom)
+                     (c-syntactic-re-search-forward
+                      "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)(" eom t))
+           (c-depropertize-raw-string
+            (match-string-no-properties 1) ; id
+            (1+ (match-beginning 0))       ; open quote
+            (match-end 1)                  ; open paren
+            eom)))))))                     ; bound.
+
+(defun c-before-change-check-raw-strings (beg end)
+  ;; This function clears `syntax-table' text properties from C++ raw strings
+  ;; in the region (c-new-BEG c-new-END).  BEG and END are the standard
+  ;; arguments supplied to any before-change function.
+  ;;
+  ;; Point is undefined on both entry and exit, and the return value has no
+  ;; significance.
+  ;;
+  ;; 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'.
+  (c-save-buffer-state
+      ((beg-rs (progn (goto-char beg) (c-raw-string-pos)))
+       (beg-plus (if (null beg-rs)
+                    beg
+                  (max beg
+                       (1+ (or (nth 4 beg-rs) (nth 2 beg-rs))))))
+       (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).
+       (end-minus (if (null end-rs)
+                     end
+                   (min end (cadr end-rs))))
+       )
+    (when beg-rs
+      (setq c-new-BEG (min c-new-BEG (1- (cadr beg-rs)))))
+    (c-depropertize-raw-strings-in-region c-new-BEG beg-plus)
+
+    (when end-rs
+      (setq c-new-END (max c-new-END
+                          (1+ (or (nth 4 end-rs)
+                                  (nth 2 end-rs))))))
+    (c-depropertize-raw-strings-in-region end-minus c-new-END)))
+
+(defun c-propertize-raw-string-opener (id open-quote open-paren bound)
+  ;; Point is immediately after a raw string opening delimiter.  Apply any
+  ;; pertinent `syntax-table' text properties to the delimiter and also the
+  ;; raw string, should there be a valid matching closing delimiter.
+  ;;
+  ;; ID, a string, is the delimiter's identifier.  OPEN-QUOTE and OPEN-PAREN
+  ;; are the buffer positions of the delimiter's components.  BOUND is the
+  ;; bound for searching for a matching closing delimiter; it is usually nil,
+  ;; but if we're inside a macro, it's the end of the macro.
+  ;;
+  ;; Point is moved to after the (terminated) raw string, or left after the
+  ;; unmatched opening delimiter, as the case may be.  The return value is of
+  ;; no significance.
+  (if (search-forward (concat ")" id "\"") bound t)
+      (let ((end-string (match-beginning 0))
+           (after-quote (match-end 0)))
+       (goto-char open-paren)
+       (while (progn (skip-syntax-forward "^\"" end-string)
+                     (< (point) end-string))
+         (c-put-char-property (point) 'syntax-table '(1)) ; punctuation
+         (forward-char))
+       (goto-char after-quote))
+    (c-put-char-property open-quote 'syntax-table '(1))             ; 
punctuation
+    (c-put-char-property open-paren 'syntax-table '(15))     ; generic string
+    (when bound
+      ;; In a CPP construct, we try to apply a generic-string `syntax-table'
+      ;; text property to the last possible character in the string, so that
+      ;; only characters within the macro get "stringed out".
+      (goto-char bound)
+      (if (save-restriction
+           (narrow-to-region (1+ open-paren) (point-max))
+           (re-search-backward
+            (eval-when-compile
+              ;; This regular expression matches either an escape pair (which
+              ;; isn't an escaped NL) (submatch 5) or a non-escaped character
+              ;; (which isn't itself a backslash) (submatch 10).  The long
+              ;; preambles to these (respectively submatches 2-4 and 6-9)
+              ;; ensure that we have the correct parity for sequences of
+              ;; backslashes, etc..
+              (concat "\\("            ; 1
+                      "\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)*" ; 
2-4
+                      "\\(\\\\.\\)"    ; 5
+                      "\\|"
+                      
"\\(\\`\\|[^\\]\\|\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)+\\)" ; 6-9
+                      "\\([^\\]\\)"    ; 10
+                      "\\)"
+                      "\\(\\\\\n\\)*\\=")) ; 11
+             (1+ open-paren) t))
+         (if (match-beginning 10)
+             (c-put-char-property (match-beginning 10) 'syntax-table '(15))
+           (c-put-char-property (match-beginning 5) 'syntax-table '(1))
+           (c-put-char-property (1+ (match-beginning 5)) 'syntax-table '(15)))
+       (c-put-char-property open-paren 'syntax-table '(1)))
+      (goto-char bound))))
+
+(defun c-after-change-re-mark-raw-strings (beg end old-len)
+  ;; This function applies `syntax-table' text properties to C++ raw strings
+  ;; beginning in the region (c-new-BEG c-new-END).  BEG, END, and OLD-LEN are
+  ;; the standard arguments supplied to any after-change function.
+  ;;
+  ;; Point is undefined on both entry and exit, and the return value has no
+  ;; significance.
+  ;; 
+  ;; This function is called as an after-change function solely due to its
+  ;; membership of the C++ value of `c-before-font-lock-functions'.
+  (c-save-buffer-state ()
+    ;; If the region (c-new-BEG c-new-END) has expanded, remove
+    ;; `syntax-table' text-properties from the new piece(s).
+    (when (< c-new-BEG c-old-BEG)
+      (let ((beg-rs (progn (goto-char c-old-BEG) (c-raw-string-pos))))
+       (c-depropertize-raw-strings-in-region
+        c-new-BEG
+        (if beg-rs
+            (1+ (or (nth 4 beg-rs) (nth 2 beg-rs)))
+          c-old-BEG))))
+    (when (> c-new-END c-old-END)
+      (let ((end-rs (progn (goto-char c-old-END) (c-raw-string-pos))))
+       (c-depropertize-raw-strings-in-region
+        (if end-rs
+            (cadr end-rs)
+          c-old-END)
+        c-new-END)))
+
+    (goto-char c-new-BEG)
+    (while (and (< (point) c-new-END)
+               (re-search-forward
+                (concat "\\("                                 ; 1
+                        c-anchored-cpp-prefix                 ; 2
+                        "\\)\\|\\("                           ; 3
+                        "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)("   ; 4
+                        "\\)")
+                c-new-END t))
+      (when (save-excursion
+             (goto-char (match-beginning 0)) (not (c-in-literal)))
+       (if (match-beginning 4)         ; the id
+           ;; We've found a raw string.
+           (c-propertize-raw-string-opener
+            (match-string-no-properties 4) ; id
+            (1+ (match-beginning 3))       ; open quote
+            (match-end 4)                  ; open paren
+            nil)                           ; bound
+         ;; We've found a CPP construct.  Search for raw strings within it.
+         (goto-char (match-beginning 2)) ; the "#"
+         (c-end-of-macro)
+         (let ((eom (point)))
+           (goto-char (match-end 2))   ; after the "#".
+           (while (and (< (point) eom)
+                       (c-syntactic-re-search-forward
+                        "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)(" eom t))
+             (c-propertize-raw-string-opener
+              (match-string-no-properties 1) ; id
+              (1+ (match-beginning 0))       ; open quote
+              (match-end 1)                  ; open paren
+              eom))))))))                    ; bound
+
 
 ;; Handling of small scale constructs like types and names.
 
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 4e83d6d..f3f369f 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -723,6 +723,10 @@ casts and declarations are fontified.  Used on level 2 and 
higher."
        (concat ".\\(" c-string-limit-regexp "\\)")
        '((c-font-lock-invalid-string)))
 
+      ;; Fontify C++ raw strings.
+      ,@(when (c-major-mode-is 'c++-mode)
+         '(c-font-lock-raw-strings))
+
       ;; Fontify keyword constants.
       ,@(when (c-lang-const c-constant-kwds)
          (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
@@ -1571,6 +1575,43 @@ casts and declarations are fontified.  Used on level 2 
and higher."
            (c-forward-syntactic-ws)
            (c-font-lock-declarators limit t in-typedef)))))))
 
+(defun c-font-lock-raw-strings (limit)
+  ;; Fontify C++ raw strings.
+  ;;
+  ;; This function will be called from font-lock for a region bounded by POINT
+  ;; and LIMIT, as though it were to identify a keyword for
+  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
+  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
+  ;; Fontification".
+  (while (search-forward-regexp
+         "R\\(\"\\)\\([^ ()\\\n\r\t]\\{,16\\}\\)(" limit t)
+    (when
+       (or (and (eobp)
+                (eq (c-get-char-property (1- (point)) 'face)
+                    'font-lock-warning-face))
+           (eq (c-get-char-property (point) 'face) 'font-lock-string-face)
+           (and (equal (c-get-char-property (match-end 2) 'syntax-table) '(1))
+                (equal (c-get-char-property (match-beginning 1) 'syntax-table)
+                       '(1))))
+      (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table)))
+       (if paren-prop
+           (progn
+             (c-put-font-lock-face (match-beginning 0) (match-end 0)
+                                   'font-lock-warning-face)
+             (when
+                 (and
+                  (equal paren-prop '(15))
+                  (not (c-search-forward-char-property 'syntax-table '(15) 
limit)))
+               (goto-char limit)))
+         (c-put-font-lock-face (match-beginning 1) (match-end 2) 'default)
+         (when (search-forward-regexp
+                (concat ")\\(" (regexp-quote (match-string-no-properties 2))
+                        "\\)\"")
+                limit t)
+           (c-put-font-lock-face (match-beginning 1) (point)
+                                 'default))))))
+  nil)
+
 (c-lang-defconst c-simple-decl-matchers
   "Simple font lock matchers for types and declarations.  These are used
 on level 2 only and so aren't combined with `c-complex-decl-matchers'."
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 18f1cc4..ba05e81 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -474,9 +474,12 @@ so that all identifiers are recognized as words.")
   ;; The value here may be a list of functions or a single function.
   t nil
   c++ '(c-extend-region-for-CPP
+       c-before-change-check-raw-strings
        c-before-change-check-<>-operators
+       c-depropertize-CPP
        c-invalidate-macro-cache)
   (c objc) '(c-extend-region-for-CPP
+            c-depropertize-CPP
             c-invalidate-macro-cache)
   ;; java 'c-before-change-check-<>-operators
   awk 'c-awk-record-region-clear-NL)
@@ -510,6 +513,7 @@ parameters \(point-min) and \(point-max).")
             c-neutralize-syntax-in-and-mark-CPP
             c-change-expand-fl-region)
   c++ '(c-extend-font-lock-region-for-macros
+       c-after-change-re-mark-raw-strings
        c-neutralize-syntax-in-and-mark-CPP
        c-restore-<>-properties
        c-change-expand-fl-region)
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 9ab0480..6f32613 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -665,6 +665,14 @@ that requires a literal mode spec at compile time."
 (make-variable-buffer-local 'c-new-BEG)
 (defvar c-new-END 0)
 (make-variable-buffer-local 'c-new-END)
+;; The following two variables record the values of `c-new-BEG' and
+;; `c-new-END' just after `c-new-END' has been adjusted for the length of text
+;; inserted or removed.  They may be read by any after-change function (but
+;; should not be altered by one).
+(defvar c-old-BEG 0)
+(make-variable-buffer-local 'c-old-BEG)
+(defvar c-old-END 0)
+(make-variable-buffer-local 'c-old-END)
 
 (defun c-common-init (&optional mode)
   "Common initialization for all CC Mode modes.
@@ -877,6 +885,31 @@ Note that the style variables are always made local to the 
buffer."
   (memq (cadr (backtrace-frame 3))
        '(put-text-property remove-list-of-text-properties)))
 
+(defun c-depropertize-CPP (beg end)
+  ;; Remove the punctuation syntax-table text property from the CPP parts of
+  ;; (c-new-BEG c-new-END).
+  ;;
+  ;; This function is in the C/C++/ObjC values of
+  ;; `c-get-state-before-change-functions' and is called exclusively as a
+  ;; before change function.
+  (goto-char c-new-BEG)
+  (while (and (< (point) beg)
+             (search-forward-regexp c-anchored-cpp-prefix beg t))
+    (goto-char (match-beginning 1))
+    (let ((m-beg (point)))
+      (c-end-of-macro)
+      (c-clear-char-property-with-value
+       m-beg (min (point) beg) 'syntax-table '(1))))
+
+  (goto-char end)
+  (while (and (< (point) c-new-END)
+             (search-forward-regexp c-anchored-cpp-prefix c-new-END t))
+    (goto-char (match-beginning 1))
+    (let ((m-beg (point)))
+      (c-end-of-macro)
+      (c-clear-char-property-with-value
+       m-beg (min (point) c-new-END) 'syntax-table '(1)))))
+
 (defun c-extend-region-for-CPP (beg end)
   ;; Adjust `c-new-BEG', `c-new-END' respectively to the beginning and end of
   ;; any preprocessor construct they may be in. 
@@ -967,9 +1000,9 @@ Note that the style variables are always made local to the 
buffer."
   ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
   ;;
   ;; This function might make hidden buffer changes.
-  (c-save-buffer-state (limits )
+  (c-save-buffer-state (limits)
     ;; Clear 'syntax-table properties "punctuation":
-    (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
+    ;; (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table 
'(1))
 
     ;; CPP "comment" markers:
     (if (eval-when-compile (memq 'category-properties c-emacs-features));Emacs.
@@ -1125,8 +1158,8 @@ Note that the style variables are always made local to 
the buffer."
 
   ;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
   ;; larger than (beg end).
-  ;; (setq c-new-BEG beg  c-new-END end)
   (setq c-new-END (- (+ c-new-END (- end beg)) old-len))
+  (setq c-old-BEG c-new-BEG  c-old-END c-new-END)
 
   (unless (c-called-from-text-property-change-p)
     (setq c-just-done-before-change nil)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]