Thank you very much for this fix, Alan. I have now tested it both with my test case and in more realistic code, and it seems to fix the issues I was encountering – thank you! Sorry for the delay on getting back to you about this. Bill Alan Mackenzie wrote on 8/2/22 1:30 PM: > Hello again, Bill. > > On Sat, Jul 30, 2022 at 17:14:43 +0300, Eli Zaretskii wrote: >>> Cc: Bill Sacks >>> Date: Sat, 30 Jul 2022 13:05:24 +0000 >>> From: Alan Mackenzie >>> 1. Start emacs -Q. >>> 2. Insert the following file in C Mode: >>> void myfunc( >>> ) { >>> } >>> 3. In line 2 (the first blank line) type "int somevar". >>> 4. Note that somevar is not fontified. This is a bug, given that the >>> arglist to myfunc is terminated with a ) on line 3. >>> 5. Do something (e.g. typing M-x) to cause a redisplay. somevar gets >>> its correct face. >>> 6. Note that any insertion or deletion in L2 causes somevar to lose its >>> fontification. This is a bug. >>> 7. (After 6). Move point onto somevar and do C-u C-x =. This shows >>> that the face text property is set on the character despite the face >>> not appearing on the screen. > This bug, although the symptoms were similar to the other bug you > reported, was an entirely different bug, more difficult to fix. > > I now have a patch for it, and would ask you to apply the patch to your > Emacs 28.1 and byte compile the files in it, as before. (As before, > help is available from me by private email.) Then please test it on > your actual C code and let us know how it went. Thanks! > > > > diff -r e4e62074b8a6 cc-engine.el > --- a/cc-engine.el Sat Jul 30 09:15:53 2022 +0000 > +++ b/cc-engine.el Tue Aug 02 19:14:15 2022 +0000 > @@ -9576,7 +9576,7 @@ > (or (= paren-depth 0) > (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) > > - (<= (point) limit) > + (< (point) limit) > > ;; Skip over any trailing bit, such as "__attribute__". > (progn > diff -r e4e62074b8a6 cc-mode.el > --- a/cc-mode.el Sat Jul 30 09:15:53 2022 +0000 > +++ b/cc-mode.el Tue Aug 02 19:14:15 2022 +0000 > @@ -2412,49 +2412,59 @@ > (and (/= new-pos pos) new-pos)))) > > (defun c-fl-decl-end (pos) > - ;; If POS is inside a declarator, return the end of the token that follows > - ;; the declarator, otherwise return nil. POS being in a literal does not > - ;; count as being in a declarator (on pragmatic grounds). POINT is not > - ;; preserved. > + ;; If POS is inside a declarator, return the position of the end of the > + ;; paren pair that terminates it, or of the end of the token that follows > + ;; the declarator, otherwise return nil. If there is no such token, the end > + ;; of the last token in the buffer is used. POS being in a literal is now > + ;; (2022-07) handled correctly. POINT is not preserved. > (goto-char pos) > (let ((lit-start (c-literal-start)) > (lim (c-determine-limit 1000)) > enclosing-attribute pos1) > - (unless lit-start > - (c-backward-syntactic-ws > - lim) > - (when (setq enclosing-attribute (c-enclosing-c++-attribute)) > - (goto-char (car enclosing-attribute))) ; Only happens in C++ Mode. > - (when (setq pos1 (c-on-identifier)) > - (goto-char pos1) > - (let ((lim (save-excursion > - (and (c-beginning-of-macro) > - (progn (c-end-of-macro) (point)))))) > - (and (c-forward-declarator lim) > - (if (eq (char-after) ?\() > - (and > - (c-go-list-forward nil lim) > - (progn (c-forward-syntactic-ws lim) > - (not (eobp))) > - (progn > - (if (looking-at c-symbol-char-key) > - ;; Deal with baz (foo((bar)) type var), where > - ;; foo((bar)) is not semantically valid. The result > - ;; must be after var). > - (and > - (goto-char pos) > - (setq pos1 (c-on-identifier)) > - (goto-char pos1) > - (progn > - (c-backward-syntactic-ws lim) > - (eq (char-before) ?\()) > - (c-fl-decl-end (1- (point)))) > - (c-backward-syntactic-ws lim) > - (point)))) > - (and (progn (c-forward-syntactic-ws lim) > - (not (eobp))) > + (if lit-start > + (goto-char lit-start)) > + (c-backward-syntactic-ws lim) > + (when (setq enclosing-attribute (c-enclosing-c++-attribute)) > + (goto-char (car enclosing-attribute)) ; Only happens in C++ Mode. > + (c-backward-syntactic-ws lim)) > + (while (and (> (point) lim) > + (memq (char-before) '(?\[ ?\())) > + (backward-char) > + (c-backward-syntactic-ws lim)) > + (when (setq pos1 (c-on-identifier)) > + (goto-char pos1) > + (let ((lim (save-excursion > + (and (c-beginning-of-macro) > + (progn (c-end-of-macro) (point)))))) > + (and (c-forward-declarator lim) > + (if (and (eq (char-after) ?\() > + (c-go-list-forward nil lim)) > + (and > + (progn (c-forward-syntactic-ws lim) > + (not (eobp))) > + (progn > + (if (looking-at c-symbol-char-key) > + ;; Deal with baz (foo((bar)) type var), where > + ;; foo((bar)) is not semantically valid. The result > + ;; must be after var). > + (and > + (goto-char pos) > + (setq pos1 (c-on-identifier)) > + (goto-char pos1) > + (progn > + (c-backward-syntactic-ws lim) > + (eq (char-before) ?\()) > + (c-fl-decl-end (1- (point)))) > (c-backward-syntactic-ws lim) > - (point))))))))) > + (point)))) > + (if (progn (c-forward-syntactic-ws lim) > + (not (eobp))) > + (c-forward-over-token) > + (let ((lit-start (c-literal-start))) > + (when lit-start > + (goto-char lit-start)) > + (c-backward-syntactic-ws))) > + (and (>= (point) pos) (point)))))))) > > (defun c-change-expand-fl-region (_beg _end _old-len) > ;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock > >