Subject: bug#56848: CC Mode fontification bug

From: Gregory Heytings <[email-masked]>
Date: Sun, 31 Jul 2022 00:16:37 +0000

Recipe:

emacs -Q
C-x C-f src/xdisp.c RET
M-g c 28 RET
;; take note of the word there: "window"
M-: (get-char-property 28 'fontified) RET
;; observe that this returns t
M-g g 800 RET
C-v
M-: (get-char-property 28 'fontified) RET
;; observe that this returns nil, because "struct window" is now visible

This is a BUG.

When font locking has put a fontified property and one of the 
font-lock-*-faces on characters in the buffer, a mode should not undo that 
unless it has a very good reason to do so.  Otherwise scrolling again 
through an already fontified buffer calls fontification functions again 
without reason.

Patch attached.

With the patch, scrolling again through an already fontified buffer is 
~25% faster.

From 4f017e72850a19fa6bfba33663652b8c638bb825 Mon Sep 17 00:00:00 2001
From: Gregory Heytings <[email-masked]>
Date: Sun, 31 Jul 2022 00:04:07 +0000
Subject: [PATCH] Be conservative with occurrences of newly found types.

* lisp/progmodes/cc-fonts.el (c-fontify-new-found-type): Remove the
fontified property on occurrences of newly found types only when
they do not yet have a face property.
---
 lisp/progmodes/cc-fonts.el | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 625010b04b..75936574a1 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -2284,16 +2284,17 @@ c-fontify-new-found-type
 	  (widen)
 	  (goto-char (point-min))
 	  (while (re-search-forward target-re nil t)
-	    (put-text-property (match-beginning 0) (match-end 0)
-			       'fontified nil)
-	    (dolist (win-boundary window-boundaries)
-	      (when (and (< (match-beginning 0) (cdr win-boundary))
-			 (> (match-end 0) (car win-boundary))
-			 (not c-re-redisplay-timer))
-		(setq c-re-redisplay-timer
-		      (run-with-timer 0 nil #'c-force-redisplay
-				      (current-buffer)
-				      (match-beginning 0) (match-end 0)))))))))))
+	    (unless (get-char-property (match-beginning 0) 'face)
+	      (put-text-property (match-beginning 0) (match-end 0)
+				 'fontified nil)
+	      (dolist (win-boundary window-boundaries)
+		(when (and (< (match-beginning 0) (cdr win-boundary))
+			   (> (match-end 0) (car win-boundary))
+			   (not c-re-redisplay-timer))
+		  (setq c-re-redisplay-timer
+			(run-with-timer 0 nil #'c-force-redisplay
+					(current-buffer)
+					(match-beginning 0) (match-end 0))))))))))))
 
 
 ;;; C.
-- 
2.35.1