Skip to content

Implement per-buffer annotation and margin system - #12

Merged
sinelaw merged 1 commit into
masterfrom
claude/annotation-margin-system-011CUpUQyApMdqhcfbgbJYCz
Nov 5, 2025
Merged

Implement per-buffer annotation and margin system#12
sinelaw merged 1 commit into
masterfrom
claude/annotation-margin-system-011CUpUQyApMdqhcfbgbJYCz

Conversation

@sinelaw

@sinelaw sinelaw commented Nov 5, 2025

Copy link
Copy Markdown
Owner

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.

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
sinelaw merged commit f871085 into master Nov 5, 2025
1 of 5 checks passed
@sinelaw
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants