comparison lisp/progmodes/cc-engine.el @ 76986:469570420bff

Fix fontification of labels, and other things with ":". * 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.
author Alan Mackenzie <acm@muc.de>
date Fri, 06 Apr 2007 21:21:55 +0000
parents a68603f8b839
children c1ec1c8a8d2e 4ef881a120fe
comparison
equal deleted inserted replaced
76985:2f0b1b082f4a 76986:469570420bff
5369 ;; `c-type-decl-suffix-key'. 5369 ;; `c-type-decl-suffix-key'.
5370 got-suffix 5370 got-suffix
5371 ;; True if there's a prefix match outside the outermost 5371 ;; True if there's a prefix match outside the outermost
5372 ;; paren pair that surrounds the declarator. 5372 ;; paren pair that surrounds the declarator.
5373 got-prefix-before-parens 5373 got-prefix-before-parens
5374 y ;; True if there's a suffix match outside the outermost 5374 ;; True if there's a suffix match outside the outermost
5375 ;; paren pair that surrounds the declarator. The value is 5375 ;; paren pair that surrounds the declarator. The value is
5376 ;; the position of the first suffix match. 5376 ;; the position of the first suffix match.
5377 got-suffix-after-parens 5377 got-suffix-after-parens
5378 ;; True if we've parsed the type decl to a token that is 5378 ;; True if we've parsed the type decl to a token that is
5379 ;; known to end declarations in this context. 5379 ;; known to end declarations in this context.
5875 c-record-ref-identifiers save-rec-ref-ids) 5875 c-record-ref-identifiers save-rec-ref-ids)
5876 nil)))) 5876 nil))))
5877 5877
5878 (defun c-forward-label (&optional assume-markup preceding-token-end limit) 5878 (defun c-forward-label (&optional assume-markup preceding-token-end limit)
5879 ;; Assuming that point is at the beginning of a token, check if it starts a 5879 ;; Assuming that point is at the beginning of a token, check if it starts a
5880 ;; label and if so move over it and return t, otherwise don't move and 5880 ;; label and if so move over it and return non-nil (t in default situations,
5881 ;; return nil. "Label" here means "most things with a colon". 5881 ;; specific symbols (see below) for interesting situations), otherwise don't
5882 ;; move and return nil. "Label" here means "most things with a colon".
5882 ;; 5883 ;;
5883 ;; More precisely, a "label" is regarded as one of: 5884 ;; More precisely, a "label" is regarded as one of:
5884 ;; (i) a goto target like "foo:"; 5885 ;; (i) a goto target like "foo:" - returns the symbol `goto-target';
5885 ;; (ii) A case label - either the entire construct "case FOO:" or just the 5886 ;; (ii) A case label - either the entire construct "case FOO:", or just the
5886 ;; bare "case", should the colon be missing; 5887 ;; bare "case", should the colon be missing. We return t;
5887 ;; (iii) a keyword which needs a colon, like "default:" or "private:"; 5888 ;; (iii) a keyword which needs a colon, like "default:" or "private:"; We
5889 ;; return t;
5888 ;; (iv) One of QT's "extended" C++ variants of 5890 ;; (iv) One of QT's "extended" C++ variants of
5889 ;; "private:"/"protected:"/"public:"/"more:" looking like "public slots:". 5891 ;; "private:"/"protected:"/"public:"/"more:" looking like "public slots:".
5892 ;; Returns the symbol `qt-2kwds-colon'.
5893 ;; (v) QT's construct "signals:". Returns the symbol `qt-1kwd-colon'.
5890 ;; (v) One of the keywords matched by `c-opt-extra-label-key' (without any 5894 ;; (v) One of the keywords matched by `c-opt-extra-label-key' (without any
5891 ;; colon). Currently (2006-03), this applies only to Objective C's 5895 ;; colon). Currently (2006-03), this applies only to Objective C's
5892 ;; keywords "@private", "@protected", and "@public". 5896 ;; keywords "@private", "@protected", and "@public". Returns t.
5893 ;; 5897 ;;
5894 ;; One of the things which will NOT be recognised as a label is a bit-field 5898 ;; One of the things which will NOT be recognised as a label is a bit-field
5895 ;; element of a struct, something like "int foo:5". 5899 ;; element of a struct, something like "int foo:5".
5896 ;; 5900 ;;
5897 ;; The end of the label is taken to be just after the colon, or the end of 5901 ;; The end of the label is taken to be just after the colon, or the end of
5916 ;; non-nil. 5920 ;; non-nil.
5917 ;; 5921 ;;
5918 ;; This function might do hidden buffer changes. 5922 ;; This function might do hidden buffer changes.
5919 5923
5920 (let ((start (point)) 5924 (let ((start (point))
5925 label-end
5921 qt-symbol-idx 5926 qt-symbol-idx
5922 macro-start) ; if we're in one. 5927 macro-start ; if we're in one.
5928 label-type)
5923 (cond 5929 (cond
5924 ;; "case" or "default" (Doesn't apply to AWK). 5930 ;; "case" or "default" (Doesn't apply to AWK).
5925 ((looking-at c-label-kwds-regexp) 5931 ((looking-at c-label-kwds-regexp)
5926 (let ((kwd-end (match-end 1))) 5932 (let ((kwd-end (match-end 1)))
5927 ;; Record only the keyword itself for fontification, since in 5933 ;; Record only the keyword itself for fontification, since in
5930 (when c-record-type-identifiers 5936 (when c-record-type-identifiers
5931 (c-record-ref-id (cons (match-beginning 1) kwd-end))) 5937 (c-record-ref-id (cons (match-beginning 1) kwd-end)))
5932 5938
5933 ;; Find the label end. 5939 ;; Find the label end.
5934 (goto-char kwd-end) 5940 (goto-char kwd-end)
5935 (if (and (c-syntactic-re-search-forward 5941 (setq label-type
5936 ;; Stop on chars that aren't allowed in expressions, 5942 (if (and (c-syntactic-re-search-forward
5937 ;; and on operator chars that would be meaningless 5943 ;; Stop on chars that aren't allowed in expressions,
5938 ;; there. FIXME: This doesn't cope with ?: operators. 5944 ;; and on operator chars that would be meaningless
5939 "[;{=,@]\\|\\(\\=\\|[^:]\\):\\([^:]\\|\\'\\)" 5945 ;; there. FIXME: This doesn't cope with ?: operators.
5940 limit t t nil 1) 5946 "[;{=,@]\\|\\(\\=\\|[^:]\\):\\([^:]\\|\\'\\)"
5941 (match-beginning 2)) 5947 limit t t nil 1)
5942 5948 (match-beginning 2))
5943 (progn 5949
5944 (goto-char (match-beginning 2)) ; just after the : 5950 (progn ; there's a proper :
5945 (c-put-c-type-property (1- (point)) 'c-decl-end) 5951 (goto-char (match-beginning 2)) ; just after the :
5946 t) 5952 (c-put-c-type-property (1- (point)) 'c-decl-end)
5947 5953 t)
5948 ;; It's an unfinished label. We consider the keyword enough 5954
5949 ;; to recognize it as a label, so that it gets fontified. 5955 ;; It's an unfinished label. We consider the keyword enough
5950 ;; Leave the point at the end of it, but don't put any 5956 ;; to recognize it as a label, so that it gets fontified.
5951 ;; `c-decl-end' marker. 5957 ;; Leave the point at the end of it, but don't put any
5952 (goto-char kwd-end) 5958 ;; `c-decl-end' marker.
5953 t))) 5959 (goto-char kwd-end)
5960 t))))
5954 5961
5955 ;; @private, @protected, @public, in Objective C, or similar. 5962 ;; @private, @protected, @public, in Objective C, or similar.
5956 ((and c-opt-extra-label-key 5963 ((and c-opt-extra-label-key
5957 (looking-at c-opt-extra-label-key)) 5964 (looking-at c-opt-extra-label-key))
5958 ;; For a `c-opt-extra-label-key' match, we record the whole 5965 ;; For a `c-opt-extra-label-key' match, we record the whole
5960 ;; Objective-C protection labels fontified. 5967 ;; Objective-C protection labels fontified.
5961 (goto-char (match-end 1)) 5968 (goto-char (match-end 1))
5962 (when c-record-type-identifiers 5969 (when c-record-type-identifiers
5963 (c-record-ref-id (cons (match-beginning 1) (point)))) 5970 (c-record-ref-id (cons (match-beginning 1) (point))))
5964 (c-put-c-type-property (1- (point)) 'c-decl-end) 5971 (c-put-c-type-property (1- (point)) 'c-decl-end)
5965 t) 5972 (setq label-type t))
5966 5973
5967 ;; All other cases of labels. 5974 ;; All other cases of labels.
5968 ((and c-recognize-colon-labels ; nil for AWK and IDL, otherwise t. 5975 ((and c-recognize-colon-labels ; nil for AWK and IDL, otherwise t.
5969 5976
5970 ;; A colon label must have something before the colon. 5977 ;; A colon label must have something before the colon.
6036 ;; this, since c-forward-syntactic-ws would foul up on it. 6043 ;; this, since c-forward-syntactic-ws would foul up on it.
6037 (unless (and c-opt-cpp-prefix (looking-at c-opt-cpp-prefix)) 6044 (unless (and c-opt-cpp-prefix (looking-at c-opt-cpp-prefix))
6038 (c-forward-syntactic-ws) 6045 (c-forward-syntactic-ws)
6039 (c-forward-label nil pte start)))))))))) 6046 (c-forward-label nil pte start))))))))))
6040 6047
6048 ;; Point is still at the beginning of the possible label construct.
6049 ;;
6041 ;; Check that the next nonsymbol token is ":", or that we're in one 6050 ;; Check that the next nonsymbol token is ":", or that we're in one
6042 ;; of QT's "slots" declarations. Allow '(' for the sake of macro 6051 ;; of QT's "slots" declarations. Allow '(' for the sake of macro
6043 ;; arguments. FIXME: Should build this regexp from the language 6052 ;; arguments. FIXME: Should build this regexp from the language
6044 ;; constants. 6053 ;; constants.
6045 (when (c-syntactic-re-search-forward 6054 (cond
6046 "[ \t[:?;{=*/%&|,<>!@+-]" limit t t) ; not at EOB 6055 ;; public: protected: private:
6047 (backward-char) 6056 ((and
6048 (setq qt-symbol-idx 6057 (c-major-mode-is 'c++-mode)
6049 (and (c-major-mode-is 'c++-mode) 6058 (search-forward-regexp
6050 (string-match 6059 "\\=p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\>[^_]" nil t)
6051 "\\(p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|more\\)\\>" 6060 (progn (backward-char)
6052 (buffer-substring start (point))))) 6061 (c-forward-syntactic-ws limit)
6053 (c-forward-syntactic-ws limit) 6062 (looking-at ":\\([^:]\\|\\'\\)"))) ; A single colon.
6054 (when (or (looking-at ":\\([^:]\\|\\'\\)") ; A single colon. 6063 (forward-char)
6055 (and qt-symbol-idx 6064 (setq label-type t))
6056 (search-forward-regexp "\\=slots\\>" limit t) 6065 ;; QT double keyword like "protected slots:" or goto target.
6057 (progn (c-forward-syntactic-ws limit) 6066 ((progn (goto-char start) nil))
6058 (looking-at ":\\([^:]\\|\\'\\)")))) ; A single colon 6067 ((when (c-syntactic-re-search-forward
6059 (forward-char) ; to after the colon. 6068 "[ \t\n[:?;{=*/%&|,<>!@+-]" limit t t) ; not at EOB
6060 t))) 6069 (backward-char)
6070 (setq label-end (point))
6071 (setq qt-symbol-idx
6072 (and (c-major-mode-is 'c++-mode)
6073 (string-match
6074 "\\(p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|more\\)\\>"
6075 (buffer-substring start (point)))))
6076 (c-forward-syntactic-ws limit)
6077 (cond
6078 ((looking-at ":\\([^:]\\|\\'\\)") ; A single colon.
6079 (forward-char)
6080 (setq label-type
6081 (if (string= "signals" ; Special QT macro
6082 (buffer-substring-no-properties start label-end))
6083 'qt-1kwd-colon
6084 'goto-target)))
6085 ((and qt-symbol-idx
6086 (search-forward-regexp "\\=slots\\>" limit t)
6087 (progn (c-forward-syntactic-ws limit)
6088 (looking-at ":\\([^:]\\|\\'\\)"))) ; A single colon
6089 (forward-char)
6090 (setq label-type 'qt-2kwds-colon)))))))
6061 6091
6062 (save-restriction 6092 (save-restriction
6063 (narrow-to-region start (point)) 6093 (narrow-to-region start (point))
6064 6094
6065 ;; Check that `c-nonlabel-token-key' doesn't match anywhere. 6095 ;; Check that `c-nonlabel-token-key' doesn't match anywhere.
6066 (catch 'check-label 6096 (catch 'check-label
6067 (goto-char start) 6097 (goto-char start)
6068 (while (progn 6098 (while (progn
6069 (when (looking-at c-nonlabel-token-key) 6099 (when (looking-at c-nonlabel-token-key)
6070 (goto-char start) 6100 (goto-char start)
6101 (setq label-type nil)
6071 (throw 'check-label nil)) 6102 (throw 'check-label nil))
6072 (and (c-safe (c-forward-sexp) 6103 (and (c-safe (c-forward-sexp)
6073 (c-forward-syntactic-ws) 6104 (c-forward-syntactic-ws)
6074 t) 6105 t)
6075 (not (eobp))))) 6106 (not (eobp)))))
6085 (c-record-ref-id (cons (match-beginning 0) 6116 (c-record-ref-id (cons (match-beginning 0)
6086 (match-end 0))))) 6117 (match-end 0)))))
6087 6118
6088 (c-put-c-type-property (1- (point-max)) 'c-decl-end) 6119 (c-put-c-type-property (1- (point-max)) 'c-decl-end)
6089 (goto-char (point-max)) 6120 (goto-char (point-max))
6090 t))) 6121 )))
6091 6122
6092 (t 6123 (t
6093 ;; Not a label. 6124 ;; Not a label.
6094 (goto-char start) 6125 (goto-char start)))
6095 nil)))) 6126 label-type))
6096 6127
6097 (defun c-forward-objc-directive () 6128 (defun c-forward-objc-directive ()
6098 ;; Assuming the point is at the beginning of a token, try to move 6129 ;; Assuming the point is at the beginning of a token, try to move
6099 ;; forward to the end of the Objective-C directive that starts 6130 ;; forward to the end of the Objective-C directive that starts
6100 ;; there. Return t if a directive was fully recognized, otherwise 6131 ;; there. Return t if a directive was fully recognized, otherwise