Skip to content

Editor: run-status gutter checkmarks land on the wrong block, don't accumulate, and don't follow edits #223

@NicolaasGrobler

Description

@NicolaasGrobler

Summary

The per-statement run-status glyphs in the editor gutter (the green ✓ / red ✗ shown next to each SQL block that was run) misbehave in several related ways. In practice it looks like "a big mess": checkmarks appear next to the wrong block, only the most recent run is marked, and they don't update when you move text around.

All three stem from one root cause, so they're tracked together here.

Bugs

  • Checkmark lands on the wrong block. When a selection containing multiple statements is run, the selected substring is re-split and the statements' line numbers are computed relative to the selection (1, 2, 3…) instead of the document. A block on document line 14 gets a glyph on line 3. (MainContent.tsx promote-to-run-all path.)
  • Only the latest run is marked. statementResults is reset to [] at the start of every execution and rebuilt fresh, so running block 2 erases block 1's checkmark. There is never "one checkmark per block that was run."
  • Glyphs don't follow edits / cut-paste. Glyphs are rebuilt from line numbers frozen at run time and re-pinned on every change, fighting Monaco's own sticky tracking. Cutting a block and pasting it elsewhere leaves the checkmark on the old (now-wrong) line, and nothing clears a glyph whose block was destroyed.

Root cause

Run status was stored as { lineNumber, status, … }[] — absolute line numbers captured at execution time — and the editor effect cleared all gutter decorations and re-created them from those frozen numbers on every change. The numbers are wrong from the start in the selection case, never accumulate, and go stale the moment the text is edited.

Steps to reproduce

  1. Open a SQL editor with two blocks separated by a blank line (each ending in ;).
  2. Run block 1 (Ctrl+Enter) → ✓ appears on block 1.
  3. Run block 2 → block 1's ✓ disappears; expected: both marked.
  4. Select both blocks and run as one selection → the second block's ✓ lands on the wrong line.
  5. Cut a marked block and paste it elsewhere → the ✓ stays on the old line instead of following or clearing.

Expected behavior (agreed)

  • One checkmark per block that has been run (accumulate; re-running a block updates its mark in place).
  • Each mark sits on the correct (document-absolute) block.
  • Marks follow in-place edits and clear when their block's text is destroyed (cut/edited away).

Fix

Implemented in the working tree:

  • New pure helpers mapSelectionStatementsToDocumentLines + mergeGlyphResults in src/utils/statementGlyphs.ts (unit-tested in src/utils/statementGlyphs.test.ts).
  • MainContent.tsx: selection statements map back to document-absolute lines; glyphs accumulate (merge + dedup by line) instead of being wiped each run.
  • QueryEditor.tsx: gutter glyphs are now id-keyed sticky Monaco decorations — reconcileGlyphs only creates new / removes gone glyphs (never re-pins survivors, so they ride along as the text shifts), and a throttled pruneGlyphs on content change drops glyphs whose anchor line was edited/cut and keeps the survivors' line numbers fresh.

Verified with npx tsc --noEmit (clean) and npm test (181 passed, incl. 7 new tests covering the relative-vs-absolute line regression and the accumulate/dedup logic).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions