Implement per-buffer annotation and margin system - #12
Merged
sinelaw merged 1 commit intoNov 5, 2025
Merged
Conversation
Implements a general-purpose, per-buffer margin system following the Emacs philosophy. Each buffer has its own independent MarginManager for flexible margin decorations. Features: - Per-buffer margin state (works correctly in split views) - Left and right margin support - Configurable margin width, separator, and styling - Support for line numbers, symbols, and stacked annotations - Event-driven API (AddMarginAnnotation, RemoveMarginAnnotation, etc.) - Helper functions for common annotations (breakpoints, errors, warnings) Implementation: - Created margin.rs module with MarginManager, MarginConfig, MarginContent - Added margin events to event.rs (serializable for undo/redo) - Integrated MarginManager into EditorState (one per buffer) - Updated rendering to use margin system instead of hardcoded line numbers - Empty buffers now render at least one line with margin Tests: - 9 unit tests for margin module (all passing) - 9 e2e tests including split view verification (all passing) - All 124 existing e2e tests still passing (no regressions) The margin system is a primitive that can be used for various features: line numbers, breakpoints, diagnostics, git blame, etc.
sinelaw
deleted the
claude/annotation-margin-system-011CUpUQyApMdqhcfbgbJYCz
branch
November 5, 2025 09:54
sinelaw
pushed a commit
that referenced
this pull request
Apr 26, 2026
Read plugin runtime, input dispatch, and render pipeline end-to-end to verify the design assumptions. Net effect on the API table: - #5 narrowed: expose existing OverlayManager::extend() fast-path as setNamespaceOverlays() instead of a generic batchDecorations wrapper — smaller change, same win. - #9 resolved: clearNamespace works as advertised at overlay.rs:319, ~1 µs for 100 overlays. - #12 added: single-global-mode constraint should be documented; plugins must save/restore prior mode themselves. No blockers found. getNextKey is essentially copy-paste from prompt's existing async pattern, wildcard binding is ~10 lines in keybindings resolution, render picks up plugin-written overlays in the same frame as the triggering keypress.
sinelaw
pushed a commit
that referenced
this pull request
Apr 26, 2026
Read plugin runtime, input dispatch, and render pipeline end-to-end to verify the design assumptions. Net effect on the API table: - #5 narrowed: expose existing OverlayManager::extend() fast-path as setNamespaceOverlays() instead of a generic batchDecorations wrapper — smaller change, same win. - #9 resolved: clearNamespace works as advertised at overlay.rs:319, ~1 µs for 100 overlays. - #12 added: single-global-mode constraint should be documented; plugins must save/restore prior mode themselves. No blockers found. getNextKey is essentially copy-paste from prompt's existing async pattern, wildcard binding is ~10 lines in keybindings resolution, render picks up plugin-written overlays in the same frame as the triggering keypress.
sinelaw
pushed a commit
that referenced
this pull request
May 4, 2026
…ehavioral findings Wave 21 — `migrated_block_selection_extras.rs` (5 tests + anti): - BlockSelectUp from line 2 col 1 selects through line 1 (5 bytes, backward). - BlockSelectRight from byte 0 selects 1 char. - BlockSelectLeft from byte 1 selects 1 char backward. - BlockSelectDown + RemoveSecondaryCursors collapses to a no-selection cursor at the active end. - BlockSelectDown + BlockSelectRight×2 + InsertChar replaces each row's prefix with the typed char. Findings recorded in `docs/internal/scenario-migration-findings.md`: - #11: `RemoveSecondaryCursors` also clears the active selection on the surviving cursor (not just removes secondaries). - #12: `AddCursorNextMatch` has three context-dependent behaviors (no-selection-with-search ⇒ select match; no-selection-no-search ⇒ select word; selection ⇒ add cursor at next occurrence). The new cursor becomes primary in the third case. Full semantic suite: 459 passed, 0 failed, 1 ignored. https://claude.ai/code/session_01XcxqHLGcChNLRCJDegA328
sinelaw
pushed a commit
that referenced
this pull request
May 4, 2026
…ehavioral findings Wave 21 — `migrated_block_selection_extras.rs` (5 tests + anti): - BlockSelectUp from line 2 col 1 selects through line 1 (5 bytes, backward). - BlockSelectRight from byte 0 selects 1 char. - BlockSelectLeft from byte 1 selects 1 char backward. - BlockSelectDown + RemoveSecondaryCursors collapses to a no-selection cursor at the active end. - BlockSelectDown + BlockSelectRight×2 + InsertChar replaces each row's prefix with the typed char. Findings recorded in `docs/internal/scenario-migration-findings.md`: - #11: `RemoveSecondaryCursors` also clears the active selection on the surviving cursor (not just removes secondaries). - #12: `AddCursorNextMatch` has three context-dependent behaviors (no-selection-with-search ⇒ select match; no-selection-no-search ⇒ select word; selection ⇒ add cursor at next occurrence). The new cursor becomes primary in the third case. Full semantic suite: 459 passed, 0 failed, 1 ignored. https://claude.ai/code/session_01XcxqHLGcChNLRCJDegA328
sinelaw
pushed a commit
that referenced
this pull request
May 27, 2026
Tested Fresh v0.3.9 built from source (target/release/fresh). All Sprints 1-9 pass: Launch, File Ops, Editing, Search/Replace, Navigation, Command Palette, Views, Tabs, Integrated Terminal, Settings UI. Bug candidates (pending GitHub search before filing): - RC12-01: Keyboard Shortcuts buffer 'q' key does not close buffer despite documentation saying it should (status: 'Editing disabled') - RC12-02: Edit menu 'Replace...' shortcut (Ctrl+Alt+R) invokes Query Replace (interactive/confirm-each), not basic Replace (Ctrl+R) Filing blocked: GitHub MCP token expired. File in Run #13. Updated test_plan.md with Sprint 10-12 items (edge cases, nav edges, bug verification). Added Run #12 entry to run_log.md. https://claude.ai/code/session_017hUKw8ZLM8GWJvQWma2SvU
sinelaw
added a commit
that referenced
this pull request
May 27, 2026
…ize backlog The per-run playbook was being silently lost: a later run overwrote learning_db.md wholesale, dropping the ISSUE FILING STANDARDS, FALSE POSITIVE PATTERNS, and Lessons 29-50 that Runs #2-11 referenced. Runs also drifted into re-verifying already-passing Sprints 1-9 (Run #12) instead of advancing the untested backlog. Fixes: - New AGENT_INSTRUCTIONS.md: the one durable, edit-rarely playbook. Folds in the hourly black-box mission + strict prohibitions (no source-code analysis, no fixes/PRs) from the external scheduler prompt. Adds STEP 0 preflight (sync, playbook-integrity check, lessons continuity, auth check, fixed-bug recheck) and ANTI-DRIFT rules R1-R4. Restores the lost ISSUE FILING STANDARDS, PRE-TESTING CHECKLIST, and FALSE POSITIVE PATTERNS (from 855bc57). - test_plan.md: RUN #13+ priority order putting the deferred edge-case/stress/navigation backlog ahead of passing sprints; pointer to the playbook and R1/R2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements a general-purpose, per-buffer margin system following the Emacs philosophy. Each buffer has its own independent MarginManager for flexible margin decorations.
Features:
Implementation:
Tests:
The margin system is a primitive that can be used for various features: line numbers, breakpoints, diagnostics, git blame, etc.