Flymake: improve previous fix (bug#78862)

The previous fix for this bug is an acceptable approach, but
more care must be taken when clearing a flymake--state object's
diagnostics.  Refactor this behaviour into a helper.

* lisp/progmodes/flymake.el (flymake--clear-state): New helper.
(flymake--publish-diagnostics, flymake-start): Use it.
This commit is contained in:
João Távora 2025-08-16 18:22:47 +01:00
parent d4c9f08f26
commit 85dcf4fe96

View file

@ -1172,6 +1172,13 @@ report applies to that region."
(flymake--state-foreign-diags state))
(clrhash (flymake--state-foreign-diags state)))
(defun flymake--clear-state (state)
(cl-loop for diag in (flymake--state-diags state)
for ov = (flymake--diag-overlay diag)
when ov do (flymake--delete-overlay ov))
(setf (flymake--state-diags state) nil)
(flymake--clear-foreign-diags state))
(defvar-local flymake-mode nil)
(defvar-local flymake--mode-line-counter-cache nil
@ -1189,7 +1196,7 @@ and other buffers."
;;
(cond
(;; If there is a `region' arg, only affect the diagnostics whose
;; overlays are in a certain region. Discard "foreign"
;; overlays are in a certain region. Ignore "foreign"
;; diagnostics.
region
(cl-loop for diag in (flymake--state-diags state)
@ -1202,16 +1209,9 @@ and other buffers."
else collect diag into surviving
finally (setf (flymake--state-diags state)
surviving)))
(;; Else, if this is the first report, zero all lists and delete
;; all associated overlays.
(;; Else, if this is the first report, fully clear this state.
(not (flymake--state-reported-p state))
(cl-loop for diag in (flymake--state-diags state)
for ov = (flymake--diag-overlay diag)
when ov do (flymake--delete-overlay ov))
(setf (flymake--state-diags state) nil)
;; Also clear all overlays for `foreign-diags' in all other
;; buffers.
(flymake--clear-foreign-diags state))
(flymake--clear-state state))
(;; If this is not the first report, do no cleanup.
t))
@ -1415,16 +1415,7 @@ Interactively, with a prefix arg, FORCE is t."
;; See bug#78862
(maphash (lambda (backend state)
(unless (memq backend flymake-diagnostic-functions)
;; Delete all overlays
(dolist (diag (flymake--state-diags state))
(let ((ov (flymake--diag-overlay diag)))
(flymake--delete-overlay ov)))
;; Set the list of diagnostics to nil to
;; avoid trying to delete them again.
;; We keep the state object itself around in
;; case there's still diagnostics in flight,
;; so we don't break things.
(setf (flymake--state-diags state) nil)))
(flymake--clear-state state)))
flymake--state)
(run-hook-wrapped
'flymake-diagnostic-functions