From c598169155621940e8842c2d53f835d6751d154f Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sat, 12 Sep 2026 14:54:53 +0700 Subject: [PATCH] Folding a frame is a display operation when there is nothing to ask --- emacs/flan-cnr.el | 8 +++++++- emacs/test-flan-cider.el | 21 +++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/emacs/flan-cnr.el b/emacs/flan-cnr.el index 67a6b57..0dfae9b 100644 --- a/emacs/flan-cnr.el +++ b/emacs/flan-cnr.el @@ -324,7 +324,13 @@ list already says it." ;; Fetched on first open and then kept: a frame's locals cannot change ;; while the program is stopped, and re-asking on every fold would put a ;; round trip behind a keystroke that looks like pure redrawing. - (when (memq i flan-cnr--open) + ;; Only when there is something to ask. The fixture tests render this + ;; buffer from a literal state with no socket behind it and no `flan-dev' + ;; loaded, and folding a frame must stay a display operation there — the + ;; renderer already draws a reason for a frame whose locals are nil, which + ;; is the same degradation every other section of this buffer uses. + (when (and (memq i flan-cnr--open) + (functionp flan-cnr-request-function)) (let ((fr (nth i (plist-get flan-cnr--state :stack)))) (when (and fr (not (plist-get fr :fetched))) (let ((answer (flan-cnr-locals i))) diff --git a/emacs/test-flan-cider.el b/emacs/test-flan-cider.el index 6c1177d..4ce93b0 100644 --- a/emacs/test-flan-cider.el +++ b/emacs/test-flan-cider.el @@ -409,8 +409,12 @@ (goto-char (point-min)) (search-forward " 1: > sim/step") (flan-cnr-toggle-frame) - (test-flan--check "a frame with no locals refuses, naming DWARF" - (string-match-p "not available.*DWARF" (buffer-string))) + ;; DWARF stopped being the reason when the shadow stack landed: a frame + ;; with nothing nameable is one whose slots the compiler invented, or whose + ;; bindings had not run. + (test-flan--check "a frame with no locals refuses, with a reason" + (string-match-p "not available.*no named locals" + (buffer-string))) (goto-char (point-min)) (search-forward " 0: v sim/settle") (flan-cnr-toggle-frame) @@ -472,7 +476,11 @@ ;; The `layout' op, from this side: the condition's own name goes out as ;; `:type' and comes back as fields with no values. Two requests are made for -;; one `C-c C-b' — `break' then `layout' — so the stub records both. +;; one `C-c C-b' — `break', `layout', then `backtrace' — so the stub records +;; all three. The assertions below look the `layout' request up by op rather +;; than by position: this list grew once already when `backtrace' landed, and a +;; positional assertion breaks every time the buffer learns to ask something +;; new, which is not what it is testing. (let ((asked nil)) (let ((flan-cnr-request-function (lambda (form) @@ -487,7 +495,12 @@ (test-flan--check "the condition's name is what `layout' is asked for" (equal (plist-get (car (last asked)) :op) "break")) (test-flan--check "and it is sent back verbatim, qualified as it came" - (equal (plist-get (car asked) :type) "sim/Missing")) + (equal (plist-get + (seq-find (lambda (f) + (equal (plist-get f :op) "layout")) + asked) + :type) + "sim/Missing")) (test-flan--check "the fields are drawn, named and typed" (string-match-p ":path *string" text)) ;; Shape and contents are two different questions, and only the first is