From ece15004709aa79faa2e19194c51699c0a86423e Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Sat, 21 Sep 2013 17:21:29 +0000 Subject: [PATCH] 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. --- lisp/ChangeLog | 9 ++++++ lisp/progmodes/cc-engine.el | 72 ++++++++++++++++++++++++++++----------------- lisp/progmodes/cc-langs.el | 16 ++++++++-- 3 files changed, 68 insertions(+), 29 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 74bcabfb575..cf5e3e1f061 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,12 @@ +2013-09-21 Alan Mackenzie + + 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 * files.el (auto-mode-alist): Support OBJFILE-gdb.gdb script files diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 582f7ef0a54..ce83efd114b 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -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 diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 80e6189822b..c1e8a1524dc 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -2587,6 +2587,15 @@ Note that Java specific rules are currently applied to tell this from ;;; 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 -- 2.11.4.GIT