Mercurial > emacs
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 |