From a84026736e4d9fa69b0d68e6a5571da240eefb64 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sun, 20 Sep 2026 12:02:43 +0700 Subject: [PATCH] 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. --- emacs/MANUAL.md | 8 +++++--- emacs/flan.el | 28 ++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/emacs/MANUAL.md b/emacs/MANUAL.md index 962b57f..3c4ecad 100644 --- a/emacs/MANUAL.md +++ b/emacs/MANUAL.md @@ -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 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, -a `clone`, a `slurp`, a new arena. Both are fainter than an error — a dotted or -dimmed underline, no message drawn beside the line — because the code is not -wrong. Hover for the sentence; the count is in the echo area. +a `clone`, a `slurp`, a new arena. The two underlines differ in style as well as +in colour, so you can tell the classes apart without relying on colour alone. +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 costs nothing, so nothing is drawn: `nil`, a `bool`, an `f64`, a keyword, and any diff --git a/emacs/flan.el b/emacs/flan.el index 611b9e5..ce17f58 100644 --- a/emacs/flan.el +++ b/emacs/flan.el @@ -2731,10 +2731,12 @@ can print the same breakdown to stderr under FLAN_DEV_LEAKS." ;; the message to find out. ;; ;; **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 -;; colour, and no per-site `after-string' — the message goes in `help-echo' and -;; the count in the echo area. An error must still win where the two land on -;; one span, which is what the lower `priority' is for. +;; is correct. So: no per-site `after-string' — which is the loud half of the +;; error overlay, a message drawn into the line — and neither face inherits +;; `error'. The message goes in `help-echo' and the count in the echo area. +;; 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 ;; 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." (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) "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) @@ -2825,12 +2836,17 @@ line that is marked. The annotations last until you edit the buffer. Asking again while they are up takes them down." (interactive) - (if (flan--memory-overlays) - (progn (flan-clear-memory) (message "flan: allocation marks off")) + (if (flan--marked-buffers) + (progn (mapc #'flan-clear-memory (flan--marked-buffers)) + (message "flan: allocation marks off")) (let ((r (flan--request (list :op "memory")))) (unless (equal (plist-get r :status) "ok") (user-error "flan: %s" (or (plist-get r :message) "refused"))) (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)) (if (flan--show-memory (nth 0 row) (nth 1 row) (nth 2 row)) (setq here (1+ here))