bug#58537: CC Mode 5.35.1 (C/*l); Keywords being fontified as types at random
Alan Mackenzie <[email protected]> Mon, 17 Oct 2022 16:19:08 +0000
| Newsgroups | gmane.emacs.cc-mode.general |
|---|---|
| Message-ID | <Y02AfPHPU56flEz+@ACM> |
Hello, Po. On Mon, Oct 17, 2022 at 14:24:59 +0800, Po Lu wrote: > Alan Mackenzie <[email protected]> writes: [ .... ] > BTW, there is still another case that isn't fixed: place the following > text in a C mode buffer: > { > Data *tem; > for (tem = surface->items; tem; tem = tem->next) > { > if (tem->type == tem) > return tem; > } > /* Next, allocate some new client data. */ > test->a = b; > } > and move point to the line above "test->a = b", and type > TAB t e m SPC = SPC foo ; > "tem" will become fontified as a type, and will also be stuck that way. Thanks for taking the trouble to report this. The problem is C Mode prematurely recognising tem in "tem \n test" as a type, since there are two adjacent identifiers. Please try out the following patch (which also includes yesterday's change). It also aims to solve the same problem when instead of test->a = b; there is test (foo); .. > Thanks. Does this patch, together with that for bug #58534 also solve #58539, or is that still giving trouble? Here is the patch: diff -r 0e4b43dec11c cc-engine.el --- a/cc-engine.el Fri Oct 14 17:13:47 2022 +0000 +++ b/cc-engine.el Mon Oct 17 15:29:55 2022 +0000 @@ -9123,7 +9123,9 @@ (when (eq name-res t) ;; In many languages the name can be used without the ;; prefix, so we add it to `c-found-types'. - (c-add-type pos (point)) + (c-add-type pos (save-excursion + (c-backward-syntactic-ws) + (point))) (when (and c-record-type-identifiers c-last-identifier-range) (c-record-type-id c-last-identifier-range))) @@ -9208,7 +9210,10 @@ (goto-char id-end) (if (or res c-promote-possible-types) (progn - (c-add-type id-start id-end) + (c-add-type id-start (save-excursion + (goto-char id-end) + (c-backward-syntactic-ws) + (point))) (when (and c-record-type-identifiers id-range) (c-record-type-id id-range)) (unless res @@ -10777,8 +10782,16 @@ (setq backup-if-not-cast t) (throw 'at-decl-or-cast t))) - (setq backup-if-not-cast t) - (throw 'at-decl-or-cast t))) + ;; If we're in declaration or template delimiters, or one + ;; of a certain set of characters follows, we've got a + ;; type and variable. + (if (or (memq context '(decl <>)) + (memq (char-after) '(?\; ?, ?= ?\( ?{ ?:))) + (progn + (setq backup-if-not-cast t) + (throw 'at-decl-or-cast t)) + ;; We're probably just typing a statement. + (throw 'at-decl-or-cast nil)))) ;; CASE 4 (when (and got-suffix @@ -10894,8 +10907,13 @@ ;; CASE 10 (when at-decl-or-cast - ;; By now we've located the type in the declaration that we know - ;; we're in. + ;; By now we've located the type in the declaration that we think + ;; we're in. Do we have enough evidence to promote the putative + ;; type to a found type? The user may be halfway through typing + ;; a statement beginning with an identifier. + (when (and (eq at-type 'maybe) + (not (eq context 'top))) + (setq c-record-type-identifiers nil)) (throw 'at-decl-or-cast t)) ;; CASE 11 diff -r 0e4b43dec11c cc-fonts.el --- a/cc-fonts.el Fri Oct 14 17:13:47 2022 +0000 +++ b/cc-fonts.el Mon Oct 17 15:29:55 2022 +0000 @@ -1200,8 +1200,21 @@ ;; arguments lists (i.e. lists enclosed by <...>) is more strict about what ;; characters it allows within the list. (let ((type (and (> match-pos (point-min)) - (c-get-char-property (1- match-pos) 'c-type)))) - (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{))) + (c-get-char-property (1- match-pos) 'c-type))) + id-pos) + (cond + ;; Are we just after something like "(foo((bar))" ? + ((and (eq (char-before match-pos) ?\)) + (c-go-list-backward match-pos) + (progn + (c-backward-syntactic-ws) + (and (setq id-pos (c-on-identifier)) + (goto-char id-pos) + (progn + (c-backward-syntactic-ws) + (eq (char-before) ?\())))) + (c-get-fontification-context (point) not-front-decl toplev)) + ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{))) (cons (and toplev 'top) nil)) ;; A control flow expression or a decltype ((and (eq (char-before match-pos) ?\() diff -r 0e4b43dec11c cc-mode.el --- a/cc-mode.el Fri Oct 14 17:13:47 2022 +0000 +++ b/cc-mode.el Mon Oct 17 15:29:55 2022 +0000 @@ -2066,13 +2066,14 @@ (defun c-update-new-id (end) ;; Note the bounds of any identifier that END is in or just after, in ;; `c-new-id-start' and `c-new-id-end'. Otherwise set these variables to - ;; nil. + ;; nil. Set `c-new-id-is-type' unconditionally to nil. (save-excursion (goto-char end) (let ((id-beg (c-on-identifier))) (setq c-new-id-start id-beg c-new-id-end (and id-beg - (progn (c-end-of-current-token) (point))))))) + (progn (c-end-of-current-token) (point))) + c-new-id-is-type nil)))) (defun c-post-command () ;; If point was inside of a new identifier and no longer is, record that -- Alan Mackenzie (Nuremberg, Germany).