bug#58883:
Alan Mackenzie <[email protected]> Thu, 17 Nov 2022 16:49:05 +0000
| Newsgroups | gmane.emacs.cc-mode.general |
|---|---|
| Message-ID | <Y3ZmAZF+Migdzy1R@ACM> |
Hello, Po. On Fri, Nov 11, 2022 at 08:48:12 +0800, Po Lu wrote: > Alan Mackenzie <[email protected]> writes: > > OK, I think I understand the problem now. I'll try to come up with a way > > of "cancelling" these "typo" found-types. > Thanks a lot! OK, I have something better than I had a week ago. Now these "typo" found-types should only exist until the typo has been corrected. Please try the attached patch, and let me know how well it works. The good news is it should fix bug #59300 "CC Mode 5.35.2 (C/*l); Yet another kind of incorrect type recognition" at the same time. [ .... ] -- Alan Mackenzie (Nuremberg, Germany).
diff.20221117.diff
(text/plain, 13.3 KB)
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index b13f6a5914..e49a736f6c 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1569,6 +1569,34 @@ c-put-char-properties-on-char
;; Miscellaneous macro(s)
+(defmacro c-get-buffer-window-list (buf)
+ ;; Either call Emacs's `get-buffer-window-list', or emulate it in XEmacs.
+ ;; The parameters are restricted as follows: BUF may be a buffer or a buffer
+ ;; name. The arguments to `get-buffer-window-list' are 'no-mini for MINIBUF
+ ;; and t for ALL-FRAMES. The result windows list is in no particular order.
+ (if (fboundp 'get-buffer-window-list)
+ ;; Emacs.
+ `(get-buffer-window-list ,buf 'no-mini t)
+ ;; XEmacs.
+ `(let ((b (get-buffer ,buf)) wlist)
+ (dolist (f (frame-list))
+ (dolist (w (window-list f 'no-mini))
+ (when (eq (window-buffer w) b)
+ (push w wlist))))
+ wlist)))
+
+(defmacro c-force-redisplay (beg end)
+ ;; Force redisplay of marker BEG's buffer between BEG and END.
+ (if (fboundp 'jit-lock-force-redisplay)
+ ;; Emacs
+ `(jit-lock-force-redisplay ,beg ,end)
+ ;; XEmacs
+ `(c-save-buffer-state ((buf (marker-buffer ,beg)))
+ (with-current-buffer buf
+ (setq ,beg (max ,beg (point-min))
+ ,end (min ,end (point-max)))
+ (put-text-property ,beg ,end 'fontified t)))))
+
(defvar c-string-fences-set-flag nil)
;; Non-nil when we have set string fences with `c-restore-string-fences'.
(defmacro c-with-string-fences (&rest forms)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 8813ec4686..174e107845 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -179,7 +179,7 @@ c-new-id-is-type
(cc-bytecomp-defun c-clear-string-fences)
(cc-bytecomp-defun c-restore-string-fences)
(cc-bytecomp-defun c-remove-string-fences)
-(cc-bytecomp-defun c-fontify-new-found-type)
+(cc-bytecomp-defun c-fontify-new/old-found-type)
;; Make declarations for all the `c-lang-defvar' variables in cc-langs.
@@ -6850,7 +6850,7 @@ c-add-type-1
; to itself in c-forward-<>-arglist.
(eq (string-match c-symbol-key type) 0)
(eq (match-end 0) (length type)))
- (c-fontify-new-found-type type)))))
+ (c-fontify-new/old-found-type type t)))))
(defun c-add-type (from to)
;; Add the given region as a type in `c-found-types'. Also perform the
@@ -6869,7 +6869,8 @@ c-add-type
(defun c-unfind-type (name)
;; Remove the "NAME" from c-found-types, if present.
- (remhash name c-found-types))
+ (remhash name c-found-types)
+ (c-fontify-new/old-found-type name nil))
(defsubst c-check-type (from to)
;; Return non-nil if the given region contains a type in
@@ -6898,38 +6899,19 @@ c-trim-found-types
;; "foo(); \n bar();". Such stale types, if not removed, foul up
;; the fontification.
;;
- ;; Have we, perhaps, added non-ws characters to the front/back of a found
- ;; type?
- (when (> end beg)
- (save-excursion
- (when (< end (point-max))
- (goto-char end)
- (if (and (c-beginning-of-current-token) ; only moves when we started in the middle
- (progn (goto-char end)
- (c-end-of-current-token)))
- (c-unfind-type (buffer-substring-no-properties
- end (point)))))
- (when (> beg (point-min))
- (goto-char beg)
- (if (and (c-end-of-current-token) ; only moves when we started in the middle
- (progn (goto-char beg)
- (c-beginning-of-current-token)))
- (c-unfind-type (buffer-substring-no-properties
- (point) beg))))))
-
(if c-maybe-stale-found-type ; e.g. (c-decl-id-start "foo" 97 107 " (* ooka) " "o")
(cond
;; Changing the amount of (already existing) whitespace - don't do anything.
((and (c-partial-ws-p beg end)
(or (= beg end) ; removal of WS
- (string-match "^[ \t\n\r\f\v]*$" (nth 5 c-maybe-stale-found-type)))))
+ (string-match "^[ \t\n\r\f\v]*$"
+ (nth 5 c-maybe-stale-found-type)))))
;; The syntactic relationship which defined a "found type" has been
;; destroyed.
- ((eq (car c-maybe-stale-found-type) 'c-decl-id-start)
- (c-unfind-type (cadr c-maybe-stale-found-type)))
-;; ((eq (car c-maybe-stale-found-type) 'c-decl-type-start) FIXME!!!
- )))
+ ((memq (car c-maybe-stale-found-type)
+ '(c-decl-id-start c-decl-type-start))
+ (c-unfind-type (cadr c-maybe-stale-found-type))))))
;; Setting and removing syntax properties on < and > in languages (C++
@@ -8546,8 +8528,10 @@ c-forward-<>-arglist
(when (consp c-record-found-types)
(let ((cur c-record-found-types))
(while (consp (car-safe cur))
- (c-fontify-new-found-type
- (buffer-substring-no-properties (caar cur) (cdar cur)))
+ (c-fontify-new/old-found-type
+ (buffer-substring-no-properties (caar cur) (cdar cur))
+ t
+ )
(setq cur (cdr cur))))
(setq c-record-type-identifiers
;; `nconc' doesn't mind that the tail of
@@ -9318,8 +9302,10 @@ c-forward-type
;; Cause the confirmed types to get fontified.
(let ((cur c-record-found-types))
(while (consp (car-safe cur))
- (c-fontify-new-found-type
- (buffer-substring-no-properties (caar cur) (cdar cur)))
+ (c-fontify-new/old-found-type
+ (buffer-substring-no-properties (caar cur) (cdar cur))
+ t
+ )
(setq cur (cdr cur))))
;; Merge in the ranges of any types found by the second
;; `c-forward-type'.
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 9444828a0e..21aae9a647 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -2498,29 +2498,31 @@ c-override-default-keywords
;; redisplay.
(defvar c-re-redisplay-timer nil)
-(defun c-force-redisplay (buffer start end)
- ;; Force redisplay immediately. This assumes `font-lock-support-mode' is
- ;; 'jit-lock-mode. Set the variable `c-re-redisplay-timer' to nil.
+(defun c-async-fontify (buffer start end redisplay)
+ ;; Fontify the given region, and redisplay it if REDISPLAY is non-nil
(with-current-buffer buffer
(save-excursion (c-font-lock-fontify-region start end))
- (jit-lock-force-redisplay (copy-marker start) (copy-marker end))
- (setq c-re-redisplay-timer nil)))
+ (if redisplay
+ (c-force-redisplay (copy-marker start) (copy-marker end)))))
-(defun c-fontify-new-found-type (type)
+(defun c-fontify-new/old-found-type (type new)
;; Cause the fontification of TYPE, a string, wherever it occurs in the
;; buffer. If TYPE is currently displayed in a window, cause redisplay to
;; happen "instantaneously". These actions are done only when jit-lock-mode
- ;; is active.
- (when (and font-lock-mode
- (boundp 'font-lock-support-mode)
- (eq font-lock-support-mode 'jit-lock-mode))
+ ;; is active. FIXME!!!
+ (when font-lock-mode
(c-save-buffer-state
- ((window-boundaries
+ ((jit (and (boundp 'font-lock-support-mode)
+ (eq font-lock-support-mode 'jit-lock-mode)))
+ (window-boundaries
(mapcar (lambda (win)
(cons (window-start win)
(window-end win)))
- (get-buffer-window-list (current-buffer) 'no-mini t)))
- (target-re (concat "\\_<" type "\\_>")))
+ (c-get-buffer-window-list (current-buffer))))
+ (target-re
+ (concat (eval-when-compile (if (featurep 'xemacs) "\\<" "\\_<"))
+ type
+ (eval-when-compile (if (featurep 'xemacs) "\\>" "\\_>")))))
(save-excursion
(save-restriction
(widen)
@@ -2530,16 +2532,28 @@ c-fontify-new-found-type
(get-text-property (match-beginning 0) 'fontified)
(not (memq (c-get-char-property (match-beginning 0) 'face)
c-literal-faces)))
- (c-put-font-lock-face (match-beginning 0) (match-end 0)
- font-lock-type-face))
- (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)))))))))))
+ (cond
+ (new
+ (c-put-font-lock-face (match-beginning 0) (match-end 0)
+ font-lock-type-face))
+ (jit
+ (put-text-property (match-beginning 0) (match-end 0)
+ 'fontified nil))
+ ;; (save-excursion
+ ;; (c-font-lock-fontify-region (match-beginning 0) (match-end 0)))
+ ;; (unless c-re-redisplay-timer
+ (t ;(setq c-re-redisplay-timer
+ (run-with-timer
+ 0 nil #'c-async-fontify
+ (current-buffer)
+ (match-beginning 0) (match-end 0)
+ (catch 'in-window
+ (dolist (win-boundary window-boundaries)
+ (when (and (< (match-beginning 0) (cdr win-boundary))
+ (> (match-end 0) (car win-boundary)))
+ (throw 'in-window t)))
+ nil)
+ ))))))))))
;;; C.
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index fb5ef69413..17a8cf93fd 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -488,18 +488,34 @@ 'c-populate-syntax-table
;; (2007-02-12): The macro `combine-after-change-calls' ISN'T used any
;; more.
-(defun c-unfind-enclosing-token (pos)
- ;; If POS is wholly inside a token, remove that id from
- ;; `c-found-types', should it be present. Return t if we were in an
- ;; id, else nil.
+(defun c-unfind-tokens-in-region (beg end)
+ ;; Remove the ids wholly or partially in the region (BEG END) from
+ ;; `c-found-types', should they be present there. If the region isn't a
+ ;; proper part of an identifier, BEG is extended to the begininng of the
+ ;; current statement. The return value is not significant.
(save-excursion
- (let ((tok-beg (progn (goto-char pos)
- (and (c-beginning-of-current-token) (point))))
- (tok-end (progn (goto-char pos)
- (and (c-end-of-current-token) (point)))))
- (when (and tok-beg tok-end)
- (c-unfind-type (buffer-substring-no-properties tok-beg tok-end))
- t))))
+ ;; Are we deleting from an identifier, but not all of it?
+ (unless (or (progn (goto-char beg)
+ (not (zerop (skip-syntax-backward c-symbol-chars))))
+ (progn (goto-char end)
+ (not (zerop (skip-syntax-forward c-symbol-chars)))))
+ (goto-char beg)
+ (unless (eq (c-beginning-of-statement-1 nil nil t) 'previous)
+ (setq beg (point))))
+
+ (goto-char beg)
+ (let* ((id-start (c-on-identifier))
+ id-end)
+ (when (and id-start
+ (progn (goto-char id-start)
+ (setq id-end (progn (c-end-of-token) (point))))
+ (> id-end beg))
+ (c-unfind-type (buffer-substring-no-properties id-start id-end)))
+ (while (and (< (point) end)
+ (re-search-forward c-symbol-start end 'bound))
+ (goto-char (match-beginning 0))
+ (re-search-forward c-symbol-key nil 'bound)
+ (c-unfind-type (match-string-no-properties 0))))))
(defun c-unfind-coalesced-tokens (beg end)
;; If removing the region (beg end) would coalesce an identifier ending at
@@ -2084,9 +2100,11 @@ c-update-new-id
(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)))
+ (setq c-new-id-end (and id-beg
+ (or (c-end-of-current-token)
+ (> end id-beg))
+ (point))
+ c-new-id-start (and c-new-id-end id-beg)
c-new-id-is-type nil))))
(defun c-post-command ()
@@ -2146,12 +2164,12 @@ c-before-change
(setq c-syntax-table-hwm most-positive-fixnum))
(save-match-data
(save-excursion
- ;; Are we inserting/deleting stuff in the middle of an
- ;; identifier?
- (c-unfind-enclosing-token beg)
- (c-unfind-enclosing-token end)
- ;; Are we coalescing two tokens together, e.g. "fo o"
- ;; -> "foo"?
+
+ ;; Remove "found" types which are going to get removed from the
+ ;; region (BEG END).
+ (c-unfind-tokens-in-region beg end)
+ ;; Are we coalescing two tokens together, e.g. "fo o" ->
+ ;; "foo"?
(when (< beg end)
(c-unfind-coalesced-tokens beg end))
(c-invalidate-sws-region-before beg end)
@@ -2174,14 +2192,14 @@ c-before-change
(when (>= end1 beg) ; Don't hassle about changes entirely in
; comments.
;; Find a limit for the search for a `c-type' property
- ;; Point is currently undefined. A `goto-char' somewhere is needed. (2020-12-06).
- (setq lim-2 (c-determine-limit 1000 (point) ; that is wrong. FIXME!!! (2020-12-06)
- ))
+ (goto-char beg)
+ (setq lim-2 (c-determine-limit 1000 (point)))
(while
(and (/= (skip-chars-backward "^;{}" lim-2) 0)
(> (point) (point-min))
(memq (c-get-char-property (1- (point)) 'face)
- '(font-lock-comment-face font-lock-string-face))))
+ '(font-lock-comment-face font-lock-string-face)))
+ (backward-char))
(setq lim (max (point-min) (1- (point))))
;; Look for the latest `c-type' property before end1
@@ -2304,11 +2322,11 @@ c-after-change
(c-clear-char-property-with-value beg end 'syntax-table nil)))
(c-update-new-id end)
- (c-trim-found-types beg end old-len) ; maybe we don't
- ; need all of these.
+ (c-trim-found-types beg end old-len)
+ ; maybe we don't need all
+ ; of these.
(c-invalidate-sws-region-after beg end old-len)
- ;; (c-invalidate-state-cache beg) ; moved to
- ;; `c-before-change'.
+ ;; (c-invalidate-state-cache beg) ; moved to `c-before-change'.
(c-invalidate-find-decl-cache beg)
(when c-recognize-<>-arglists