C++: fontify identifier in declaration following "public:" correctly.
authorAlan Mackenzie <acm@muc.de>
Sat, 21 Sep 2013 17:21:29 +0000 (17:21 +0000)
committerAlan Mackenzie <acm@muc.de>
Sat, 21 Sep 2013 17:21:29 +0000 (17:21 +0000)
* progmodes/cc-langs.el (c-decl-start-colon-kwd-re): New lang var
to match "public", etc.
(c-decl-prefix-re): Add ":" into the C++ value.
* progmodes/cc-engine.el (c-find-decl-prefix-search): Refactor a
bit.  Add a check for a ":" preceded by "public", etc.

lisp/ChangeLog
lisp/progmodes/cc-engine.el
lisp/progmodes/cc-langs.el

index 74bcabf..cf5e3e1 100644 (file)
@@ -1,3 +1,12 @@
+2013-09-21  Alan Mackenzie  <acm@muc.de>
+
+       C++: fontify identifier in declaration following "public:" correctly.
+       * progmodes/cc-langs.el (c-decl-start-colon-kwd-re): New lang var
+       to match "public", etc.
+       (c-decl-prefix-re): Add ":" into the C++ value.
+       * progmodes/cc-engine.el (c-find-decl-prefix-search): Refactor a
+       bit.  Add a check for a ":" preceded by "public", etc.
+
 2013-09-21  Eli Zaretskii  <eliz@gnu.org>
 
        * files.el (auto-mode-alist): Support OBJFILE-gdb.gdb script files
index 582f7ef..ce83efd 100644 (file)
@@ -4729,6 +4729,11 @@ comment at the start of cc-engine.el for more info."
   ;; inside `c-find-decl-spots'.  The point is left at `cfd-match-pos'
   ;; if there is a match, otherwise at `cfd-limit'.
   ;;
+  ;; The macro moves point forward to the next putative start of a declaration
+  ;; or cfd-limit.  This decl start is the next token after a "declaration
+  ;; prefix".  The declaration prefix is the earlier of `cfd-prop-match' and
+  ;; `cfd-re-match'.  `cfd-match-pos' is set to the decl prefix.
+  ;;
   ;; This macro might do hidden buffer changes.
 
   '(progn
@@ -4750,34 +4755,47 @@ comment at the start of cc-engine.el for more info."
        (if (> cfd-re-match-end (point))
           (goto-char cfd-re-match-end))
 
-       (while (if (setq cfd-re-match-end
-                       (re-search-forward c-decl-prefix-or-start-re
-                                          cfd-limit 'move))
-
-                 ;; Match.  Check if it's inside a comment or string literal.
-                 (c-got-face-at
-                  (if (setq cfd-re-match (match-end 1))
-                      ;; Matched the end of a token preceding a decl spot.
-                      (progn
-                        (goto-char cfd-re-match)
-                        (1- cfd-re-match))
-                    ;; Matched a token that start a decl spot.
-                    (goto-char (match-beginning 0))
-                    (point))
-                  c-literal-faces)
-
-               ;; No match.  Finish up and exit the loop.
-               (setq cfd-re-match cfd-limit)
-               nil)
-
-        ;; Skip out of comments and string literals.
-        (while (progn
-                 (goto-char (next-single-property-change
-                             (point) 'face nil cfd-limit))
-                 (and (< (point) cfd-limit)
-                      (c-got-face-at (point) c-literal-faces)))))
+       ;; Each time round, the next `while' moves forward over a pseudo match
+       ;; of `c-decl-prefix-or-start-re' which is either inside a literal, or
+       ;; is a ":" not preceded by "public", etc..  `cfd-re-match' and
+       ;; `cfd-re-match-end' get set.
+       (while
+          (progn
+            (setq cfd-re-match-end (re-search-forward c-decl-prefix-or-start-re
+                                                      cfd-limit 'move))
+            (cond
+             ((null cfd-re-match-end)
+              ;; No match.  Finish up and exit the loop.
+              (setq cfd-re-match cfd-limit)
+              nil)
+             ((c-got-face-at
+               (if (setq cfd-re-match (match-end 1))
+                   ;; Matched the end of a token preceding a decl spot.
+                   (progn
+                     (goto-char cfd-re-match)
+                     (1- cfd-re-match))
+                 ;; Matched a token that start a decl spot.
+                 (goto-char (match-beginning 0))
+                 (point))
+               c-literal-faces)
+              ;; Pseudo match inside a comment or string literal.  Skip out
+              ;; of comments and string literals.
+              (while (progn
+                       (goto-char (next-single-property-change
+                                   (point) 'face nil cfd-limit))
+                       (and (< (point) cfd-limit)
+                            (c-got-face-at (point) c-literal-faces))))
+              t)                     ; Continue the loop over pseudo matches.
+             ((and (match-string 1)
+                   (string= (match-string 1) ":")
+                   (save-excursion
+                     (or (/= (c-backward-token-2 2) 0) ; no search limit.  :-(
+                         (not (looking-at c-decl-start-colon-kwd-re)))))
+              ;; Found a ":" which isn't part of "public:", etc.
+              t)
+             (t nil)))) ;; Found a real match.  Exit the pseudo-match loop.
 
-       ;; If we matched at the decl start, we have to back up over the
+       ;; If our match was at the decl start, we have to back up over the
        ;; preceding syntactic ws to set `cfd-match-pos' and to catch
        ;; any decl spots in the syntactic ws.
        (unless cfd-re-match
index 80e6189..c1e8a15 100644 (file)
@@ -2587,6 +2587,15 @@ Note that Java specific rules are currently applied to tell this from
 \f
 ;;; Additional constants for parser-level constructs.
 
+(c-lang-defconst c-decl-start-colon-kwd-re
+  "Regexp matching a keyword that is followed by a colon, where
+  the whole construct can precede a declaration.
+  E.g. \"public:\" in C++."
+  t "\\<\\>"
+  c++ (c-make-keywords-re t (c-lang-const c-protection-kwds)))
+(c-lang-defvar c-decl-start-colon-kwd-re
+  (c-lang-const c-decl-start-colon-kwd-re))
+
 (c-lang-defconst c-decl-prefix-re
   "Regexp matching something that might precede a declaration, cast or
 label, such as the last token of a preceding statement or declaration.
@@ -2626,8 +2635,11 @@ more info."
   java "\\([\{\}\(;,<]+\\)"
   ;; Match "<" in C++ to get the first argument in a template arglist.
   ;; In that case there's an additional check in `c-find-decl-spots'
-  ;; that it got open paren syntax.
-  c++ "\\([\{\}\(\);,<]+\\)"
+  ;; that it got open paren syntax.  Match ":" to aid in picking up
+  ;; "public:", etc.  This involves additional checks in
+  ;; `c-find-decl-prefix-search' to prevent a match of identifiers
+  ;; or labels.
+  c++ "\\([\{\}\(\);:,<]+\\)"
   ;; Additionally match the protection directives in Objective-C.
   ;; Note that this doesn't cope with the longer directives, which we
   ;; would have to match from start to end since they don't end with