]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix fontification of labels, and other things with ":".
authorAlan Mackenzie <acm@muc.de>
Fri, 6 Apr 2007 21:21:55 +0000 (21:21 +0000)
committerAlan Mackenzie <acm@muc.de>
Fri, 6 Apr 2007 21:21:55 +0000 (21:21 +0000)
* progmodes/cc-engine.el (c-forward-label): The function now
returns 'goto-target, 'qt-2kwds-colon, 'qt-1kwd-colon, as well as
the former t.

* progmodes/cc-fonts.el (c-font-lock-declarations): Interpret the
new return code from c-forward-label, fontifying tokens properly.
Add some general comments throughout the file.

lisp/progmodes/cc-engine.el
lisp/progmodes/cc-fonts.el

index a9641b8eda0bb48e78ca2eb9f35702deea1c1b1d..717016af7eae97d09d3e5ed60a66caefde64c5c8 100644 (file)
@@ -5371,7 +5371,7 @@ comment at the start of cc-engine.el for more info."
          ;; True if there's a prefix match outside the outermost
          ;; paren pair that surrounds the declarator.
          got-prefix-before-parens
-y        ;; True if there's a suffix match outside the outermost
+         ;; True if there's a suffix match outside the outermost
          ;; paren pair that surrounds the declarator.  The value is
          ;; the position of the first suffix match.
          got-suffix-after-parens
@@ -5877,19 +5877,23 @@ y         ;; True if there's a suffix match outside the outermost
 
 (defun c-forward-label (&optional assume-markup preceding-token-end limit)
   ;; Assuming that point is at the beginning of a token, check if it starts a
-  ;; label and if so move over it and return t, otherwise don't move and
-  ;; return nil.  "Label" here means "most things with a colon".
+  ;; label and if so move over it and return non-nil (t in default situations,
+  ;; specific symbols (see below) for interesting situations), otherwise don't
+  ;; move and return nil.  "Label" here means "most things with a colon".
   ;;
   ;; More precisely, a "label" is regarded as one of:
-  ;; (i) a goto target like "foo:";
-  ;; (ii) A case label - either the entire construct "case FOO:" or just the
-  ;;   bare "case", should the colon be missing;
-  ;; (iii) a keyword which needs a colon, like "default:" or "private:";
+  ;; (i) a goto target like "foo:" - returns the symbol `goto-target';
+  ;; (ii) A case label - either the entire construct "case FOO:", or just the
+  ;;   bare "case", should the colon be missing.  We return t;
+  ;; (iii) a keyword which needs a colon, like "default:" or "private:";  We
+  ;;   return t;
   ;; (iv) One of QT's "extended" C++ variants of
-  ;; "private:"/"protected:"/"public:"/"more:" looking like "public slots:".
+  ;;   "private:"/"protected:"/"public:"/"more:" looking like "public slots:".
+  ;;   Returns the symbol `qt-2kwds-colon'.
+  ;; (v) QT's construct "signals:".  Returns the symbol `qt-1kwd-colon'.
   ;; (v) One of the keywords matched by `c-opt-extra-label-key' (without any
   ;;   colon).  Currently (2006-03), this applies only to Objective C's
-  ;;   keywords "@private", "@protected", and "@public".
+  ;;   keywords "@private", "@protected", and "@public".  Returns t.
   ;;
   ;; One of the things which will NOT be recognised as a label is a bit-field
   ;; element of a struct, something like "int foo:5".
@@ -5918,8 +5922,10 @@ y          ;; True if there's a suffix match outside the outermost
   ;; This function might do hidden buffer changes.
 
   (let ((start (point))
+       label-end
        qt-symbol-idx
-       macro-start)                    ; if we're in one.
+       macro-start                     ; if we're in one.
+       label-type)
     (cond
      ;; "case" or "default" (Doesn't apply to AWK). 
      ((looking-at c-label-kwds-regexp)
@@ -5932,25 +5938,26 @@ y         ;; True if there's a suffix match outside the outermost
 
        ;; Find the label end.
        (goto-char kwd-end)
-       (if (and (c-syntactic-re-search-forward
-                 ;; Stop on chars that aren't allowed in expressions,
-                 ;; and on operator chars that would be meaningless
-                 ;; there.  FIXME: This doesn't cope with ?: operators.
-                 "[;{=,@]\\|\\(\\=\\|[^:]\\):\\([^:]\\|\\'\\)"
-                 limit t t nil 1)
-                (match-beginning 2))
-
-           (progn
-             (goto-char (match-beginning 2)) ; just after the :
-             (c-put-c-type-property (1- (point)) 'c-decl-end)
-             t)
-
-         ;; It's an unfinished label.  We consider the keyword enough
-         ;; to recognize it as a label, so that it gets fontified.
-         ;; Leave the point at the end of it, but don't put any
-         ;; `c-decl-end' marker.
-         (goto-char kwd-end)
-         t)))
+       (setq label-type
+             (if (and (c-syntactic-re-search-forward
+                       ;; Stop on chars that aren't allowed in expressions,
+                       ;; and on operator chars that would be meaningless
+                       ;; there.  FIXME: This doesn't cope with ?: operators.
+                       "[;{=,@]\\|\\(\\=\\|[^:]\\):\\([^:]\\|\\'\\)"
+                       limit t t nil 1)
+                      (match-beginning 2))
+
+                 (progn                ; there's a proper :
+                   (goto-char (match-beginning 2)) ; just after the :
+                   (c-put-c-type-property (1- (point)) 'c-decl-end)
+                   t)
+
+             ;; It's an unfinished label.  We consider the keyword enough
+             ;; to recognize it as a label, so that it gets fontified.
+             ;; Leave the point at the end of it, but don't put any
+             ;; `c-decl-end' marker.
+               (goto-char kwd-end)
+               t))))
 
      ;; @private, @protected, @public, in Objective C, or similar.
      ((and c-opt-extra-label-key
@@ -5962,7 +5969,7 @@ y   ;; True if there's a suffix match outside the outermost
       (when c-record-type-identifiers
        (c-record-ref-id (cons (match-beginning 1) (point))))
       (c-put-c-type-property (1- (point)) 'c-decl-end)
-      t)
+      (setq label-type t))
 
      ;; All other cases of labels.
      ((and c-recognize-colon-labels    ; nil for AWK and IDL, otherwise t.
@@ -6038,26 +6045,49 @@ y         ;; True if there's a suffix match outside the outermost
                         (c-forward-syntactic-ws)
                         (c-forward-label nil pte start))))))))))
 
+          ;; Point is still at the beginning of the possible label construct.
+          ;; 
           ;; Check that the next nonsymbol token is ":", or that we're in one
           ;; of QT's "slots" declarations.  Allow '(' for the sake of macro
           ;; arguments.  FIXME: Should build this regexp from the language
           ;; constants.
-          (when (c-syntactic-re-search-forward
-                 "[ \t[:?;{=*/%&|,<>!@+-]" limit t t) ; not at EOB
-            (backward-char)
-            (setq qt-symbol-idx
-                  (and (c-major-mode-is 'c++-mode)
-                       (string-match
-                        "\\(p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|more\\)\\>"
-                        (buffer-substring start (point)))))
-            (c-forward-syntactic-ws limit)
-            (when (or (looking-at ":\\([^:]\\|\\'\\)") ; A single colon.
-                      (and qt-symbol-idx
-                           (search-forward-regexp "\\=slots\\>" limit t)
-                           (progn (c-forward-syntactic-ws limit)
-                                  (looking-at ":\\([^:]\\|\\'\\)")))) ; A single colon
-              (forward-char)           ; to after the colon.
-              t)))
+          (cond
+           ;; public: protected: private:
+           ((and
+             (c-major-mode-is 'c++-mode)
+             (search-forward-regexp
+              "\\=p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\>[^_]" nil t)
+             (progn (backward-char)
+                    (c-forward-syntactic-ws limit)
+                    (looking-at ":\\([^:]\\|\\'\\)"))) ; A single colon.
+            (forward-char)
+            (setq label-type t))
+           ;; QT double keyword like "protected slots:" or goto target.
+           ((progn (goto-char start) nil))
+           ((when (c-syntactic-re-search-forward
+                   "[ \t\n[:?;{=*/%&|,<>!@+-]" limit t t) ; not at EOB
+              (backward-char)
+              (setq label-end (point))
+              (setq qt-symbol-idx
+                    (and (c-major-mode-is 'c++-mode)
+                         (string-match
+                          "\\(p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|more\\)\\>"
+                          (buffer-substring start (point)))))  
+              (c-forward-syntactic-ws limit)
+              (cond
+               ((looking-at ":\\([^:]\\|\\'\\)") ; A single colon.
+                (forward-char)
+                (setq label-type
+                      (if (string= "signals" ; Special QT macro
+                                   (buffer-substring-no-properties start label-end))
+                          'qt-1kwd-colon
+                        'goto-target)))
+               ((and qt-symbol-idx
+                     (search-forward-regexp "\\=slots\\>" limit t)
+                     (progn (c-forward-syntactic-ws limit)
+                            (looking-at ":\\([^:]\\|\\'\\)"))) ; A single colon
+                (forward-char)
+                (setq label-type 'qt-2kwds-colon)))))))
 
       (save-restriction
        (narrow-to-region start (point))
@@ -6068,6 +6098,7 @@ y   ;; True if there's a suffix match outside the outermost
          (while (progn
                   (when (looking-at c-nonlabel-token-key)
                     (goto-char start)
+                    (setq label-type nil)
                     (throw 'check-label nil))
                   (and (c-safe (c-forward-sexp)
                                (c-forward-syntactic-ws)
@@ -6087,12 +6118,12 @@ y         ;; True if there's a suffix match outside the outermost
 
          (c-put-c-type-property (1- (point-max)) 'c-decl-end)
          (goto-char (point-max))
-         t)))
+         )))
 
      (t
       ;; Not a label.
-      (goto-char start)
-      nil))))
+      (goto-char start)))
+    label-type))
 
 (defun c-forward-objc-directive ()
   ;; Assuming the point is at the beginning of a token, try to move
index a880ae9a1fe546803a5548c4ce3a5ddaf7bd1be5..0df09eda481fc39126b1b19591019829c82ac9ed 100644 (file)
@@ -704,8 +704,13 @@ casts and declarations are fontified.  Used on level 2 and higher."
       ))
 
 (defun c-font-lock-complex-decl-prepare (limit)
+  ;; 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".
+  ;;
   ;; Called before any of the matchers in `c-complex-decl-matchers'.
-  ;; Nil is always returned.
   ;;
   ;; This function does hidden buffer changes.
 
@@ -742,10 +747,15 @@ casts and declarations are fontified.  Used on level 2 and higher."
   nil)
 
 (defun c-font-lock-<>-arglists (limit)
+  ;; 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".
+  ;;
   ;; Fontify types and references in names containing angle bracket
   ;; arglists from the point to LIMIT.  Note that
-  ;; `c-font-lock-declarations' already has handled many of them.  Nil
-  ;; is always returned.
+  ;; `c-font-lock-declarations' already has handled many of them.
   ;;
   ;; This function might do hidden buffer changes.
 
@@ -971,9 +981,14 @@ casts and declarations are fontified.  Used on level 2 and higher."
        font-lock-keyword-face))
 
 (defun c-font-lock-declarations (limit)
+  ;; 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".
+  ;;
   ;; Fontify all the declarations, casts and labels from the point to LIMIT.
-  ;; Assumes that strings and comments have been fontified already.  Nil is
-  ;; always returned.
+  ;; Assumes that strings and comments have been fontified already.
   ;;
   ;; This function might do hidden buffer changes.
 
@@ -1009,6 +1024,7 @@ casts and declarations are fontified.  Used on level 2 and higher."
          ;; `c-forward-decl-or-cast-1' and `c-forward-label' for
          ;; later fontification.
          (c-record-type-identifiers t)
+         label-type
          c-record-ref-identifiers
          ;; Make `c-forward-type' calls mark up template arglists if
          ;; it finds any.  That's necessary so that we later will
@@ -1174,39 +1190,31 @@ casts and declarations are fontified.  Used on level 2 and higher."
              (c-fontify-recorded-types-and-refs)
              nil))
 
-         ;; It was a false alarm.
+         ;; It was a false alarm.  Check if we're in a label (or other
+         ;; construct with `:' except bitfield) instead.
          (goto-char start-pos)
-         ;; The below code attempts to fontify the case constants in
-         ;; c-label-face-name, but it cannot catch every case [sic].
-         ;; And do we want to fontify case constants anyway?
-         (c-forward-label t match-pos nil)
-;;;      (when (c-forward-label t match-pos nil)
-;;;        ;; Can't use `c-fontify-types-and-refs' here since we
-;;;        ;; should use the label face.
-;;;        (save-excursion
-;;;          (while c-record-ref-identifiers
-;;;            (let ((elem (car c-record-ref-identifiers))
-;;;                  c-record-type-identifiers)
-;;;              (goto-char (cdr elem))
-;;;              ;; Find the end of any label.
-;;;              (while (and (re-search-forward "\\sw\\|:" nil t)
-;;;                          (progn (backward-char 1) t)
-;;;                          (or (re-search-forward
-;;;                               "\\=0[Xx][0-9A-Fa-f]+\\|\\([0-9]+\\)" nil t)
-;;;                              (c-forward-name)))
-;;;                (c-backward-syntactic-ws)
-;;;                (let ((end (point)))
-;;;                  ;; Now find the start of the bit we regard as the label.
-;;;                  (when (and (c-simple-skip-symbol-backward)
-;;;                             (not (c-get-char-property (point) 'face)))
-;;;                    (c-put-font-lock-face (point) end c-label-face-name))
-;;;                  (goto-char end))))
-;;;            (setq c-record-ref-identifiers (cdr c-record-ref-identifiers))))
-;;;        ;; `c-forward-label' probably has added a `c-decl-end'
-;;;        ;; marker, so return t to `c-find-decl-spots' to signal
-;;;        ;; that.
-;;;        t)
-         )))
+         (when (setq label-type (c-forward-label t match-pos nil))
+           ;; Can't use `c-fontify-types-and-refs' here since we
+           ;; use the label face at times.
+           (cond ((eq label-type 'goto-target)
+                  (c-put-font-lock-face (caar c-record-ref-identifiers)
+                                        (cdar c-record-ref-identifiers)
+                                        c-label-face-name))
+                 ((eq label-type 'qt-1kwd-colon)
+                  (c-put-font-lock-face (caar c-record-ref-identifiers)
+                                        (cdar c-record-ref-identifiers)
+                                        'font-lock-keyword-face))
+                 ((eq label-type 'qt-2kwds-colon)
+                  (mapc
+                   (lambda (kwd)
+                     (c-put-font-lock-face (car kwd) (cdr kwd)
+                                           'font-lock-keyword-face))
+                   c-record-ref-identifiers)))
+           (setq c-record-ref-identifiers nil)
+           ;; `c-forward-label' has probably added a `c-decl-end'
+           ;; marker, so return t to `c-find-decl-spots' to signal
+           ;; that.
+           t))))
 
       nil)))
 
@@ -1285,6 +1293,14 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
   "Complex font lock matchers for types and declarations.  Used on level
 3 and higher."
 
+  ;; Note: This code in this form dumps a number of funtions into the
+  ;; resulting constant, `c-matchers-3'.  At run time, font lock will call
+  ;; each of them as a "FUNCTION" (see Elisp page "Search-based
+  ;; Fontification").  The font lock region is delimited by POINT and the
+  ;; single parameter, LIMIT.  Each of these functions returns NIL (thus
+  ;; inhibiting spurious font-lock-keyword-face highlighting and another
+  ;; call).
+
   t `(;; Initialize some things before the search functions below.
       c-font-lock-complex-decl-prepare
 
@@ -1397,6 +1413,8 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
 
       ;; Fontify the type in C++ "new" expressions.
       ,@(when (c-major-mode-is 'c++-mode)
+         ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)"
+         ;; (see Elisp page "Search-based Fontification").
          `(("\\<new\\>"
             (c-font-lock-c++-new))))
       ))