Package: emacs;
Reported by: Alan Mackenzie <acm <at> muc.de>
Date: Sat, 30 Jul 2022 13:06:01 UTC
Severity: minor
Done: Alan Mackenzie <acm <at> muc.de>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Bill Sacks <sacks <at> ucar.edu> To: Alan Mackenzie <acm <at> muc.de> Cc: 56841 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org> Subject: bug#56841: Emacs-28 C Mode: Fontification errors when arglist closing ) is on next line Date: Mon, 22 Aug 2022 10:08:48 -0600
[Message part 1 (text/plain, inline)]
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 <sacks <at> ucar.edu> >>> Date: Sat, 30 Jul 2022 13:05:24 +0000 >>> From: Alan Mackenzie <acm <at> muc.de> >>> 1. Start emacs -Q. >>> 2. Insert the following file in C Mode: >>> void myfunc( >>> ) { >>> } >>> 3. In line 2 (the first blank line) type "<TAB>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 > >
[Message part 2 (text/html, inline)]
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.