One request paints every open buffer, so the toggle has to ask about all of them

flan-check-memory painted every buffer visiting a file the answer named
but decided whether it was already on by looking at the current one.
Asking again from a third buffer therefore stacked a second copy on the
two that were marked, with a second help-echo, and the toggle in the
third buffer took nothing down. Both the toggle and the repaint now go
through the whole buffer list.

The comment beside the faces claimed a dotted underline. The gc face
draws a wave, the same style the error face does; what actually makes
these fainter is that neither inherits error and neither draws its
message into the line. Say that instead, in flan.el and in MANUAL.md.
This commit is contained in:
Joseph Ferano 2026-09-20 12:02:43 +07:00
parent 5b0062219e
commit a84026736e
2 changed files with 27 additions and 9 deletions

View File

@ -562,9 +562,11 @@ this frame's memory going".
collected heap: a string, a vec or a map crossing into `dyn`, the view record a collected heap: a string, a vec or a map crossing into `dyn`, the view record a
typed container takes when it crosses, an `i64` too wide for a `dyn`'s payload. typed container takes when it crosses, an `i64` too wide for a `dyn`'s payload.
Another for an allocator the program named: a push or a `reserve` past capacity, Another for an allocator the program named: a push or a `reserve` past capacity,
a `clone`, a `slurp`, a new arena. Both are fainter than an error — a dotted or a `clone`, a `slurp`, a new arena. The two underlines differ in style as well as
dimmed underline, no message drawn beside the line — because the code is not in colour, so you can tell the classes apart without relying on colour alone.
wrong. Hover for the sentence; the count is in the echo area. Both are fainter than an error: neither inherits the error face, and neither
draws its message into the line the way a rejection does. Hover for the
sentence; the count is in the echo area.
**What is deliberately not marked is the half worth knowing.** A `dyn` immediate **What is deliberately not marked is the half worth knowing.** A `dyn` immediate
costs nothing, so nothing is drawn: `nil`, a `bool`, an `f64`, a keyword, and any costs nothing, so nothing is drawn: `nil`, a `bool`, an `f64`, a keyword, and any

View File

@ -2731,10 +2731,12 @@ can print the same breakdown to stderr under FLAN_DEV_LEAKS."
;; the message to find out. ;; the message to find out.
;; ;;
;; **Fainter than an error, deliberately.** These are annotations on code that ;; **Fainter than an error, deliberately.** These are annotations on code that
;; is correct. So: a dotted underline rather than an error's wave, a dimmed ;; is correct. So: no per-site `after-string' — which is the loud half of the
;; colour, and no per-site `after-string' — the message goes in `help-echo' and ;; error overlay, a message drawn into the line — and neither face inherits
;; the count in the echo area. An error must still win where the two land on ;; `error'. The message goes in `help-echo' and the count in the echo area.
;; one span, which is what the lower `priority' is for. ;; The two underlines differ in style as well as in colour, so the classes are
;; told apart without relying on colour alone. An error must still win where
;; the two land on one span, which is what the lower `priority' is for.
;; ;;
;; **And they last, which an error overlay does not.** The error overlay is ;; **And they last, which an error overlay does not.** The error overlay is
;; feedback about the evaluation that just failed, so any command at all takes ;; feedback about the evaluation that just failed, so any command at all takes
@ -2777,6 +2779,15 @@ what makes that reading stale — nothing smaller does, which is why this is
not the `pre-command-hook' the error overlays use." not the `pre-command-hook' the error overlays use."
(flan-clear-memory)) (flan-clear-memory))
(defun flan--marked-buffers ()
"Every buffer that currently has allocation annotations in it.
One request paints every buffer visiting a file the answer names, so the
toggle and the refresh are questions about all of them and not about the
one point happens to be in: asking from a third buffer would otherwise
stack a second copy on the two that were already marked."
(seq-filter (lambda (b) (flan--memory-overlays b)) (buffer-list)))
(defun flan--memory-face (kind) (defun flan--memory-face (kind)
"The face for a diagnostic of KIND, or nil if KIND is not one of ours." "The face for a diagnostic of KIND, or nil if KIND is not one of ours."
(cond ((equal kind "memory/gc") 'flan-memory-gc-face) (cond ((equal kind "memory/gc") 'flan-memory-gc-face)
@ -2825,12 +2836,17 @@ line that is marked.
The annotations last until you edit the buffer. Asking again while they are The annotations last until you edit the buffer. Asking again while they are
up takes them down." up takes them down."
(interactive) (interactive)
(if (flan--memory-overlays) (if (flan--marked-buffers)
(progn (flan-clear-memory) (message "flan: allocation marks off")) (progn (mapc #'flan-clear-memory (flan--marked-buffers))
(message "flan: allocation marks off"))
(let ((r (flan--request (list :op "memory")))) (let ((r (flan--request (list :op "memory"))))
(unless (equal (plist-get r :status) "ok") (unless (equal (plist-get r :status) "ok")
(user-error "flan: %s" (or (plist-get r :message) "refused"))) (user-error "flan: %s" (or (plist-get r :message) "refused")))
(let ((here 0) (elsewhere 0)) (let ((here 0) (elsewhere 0))
;; Nothing was marked in *this* buffer or the branch above would have
;; run — but another one may be, and painting over it would stack a
;; second copy with a second `help-echo'.
(mapc #'flan-clear-memory (flan--marked-buffers))
(dolist (row (plist-get r :sites)) (dolist (row (plist-get r :sites))
(if (flan--show-memory (nth 0 row) (nth 1 row) (nth 2 row)) (if (flan--show-memory (nth 0 row) (nth 1 row) (nth 2 row))
(setq here (1+ here)) (setq here (1+ here))