Commit Graph

4 Commits

Author SHA1 Message Date
Levi Neuwirth 4222ffae6e docs(folding): Stage 2 framing rev 4 — address review round 3
Route command-time visible-line maps through each operation's target
window, while retaining the acting frontend as the projection-policy
owner. Model nested and crossing folds as merged hidden components so
row and byte clamps always resolve to one actually visible head.

Also key projection on the negotiated render selection and correct the
unmerged status of the separate Stage 1 housekeeping PR.
2026-07-23 17:25:55 -04:00
Levi Neuwirth 8160d660a0 docs(folding): Stage 2 framing rev 3 — address review round 2
Round 2's three findings + two nits, all verified against c49a8c7:

- F1 (major): fold-aware motion must be frontend-projection scoped. Shared
  EditorCore::move_up/down/page_* would make a simultaneous unfolded GPU
  session skip source lines it still displays (a grid + a semantic session
  can attach to one buffer, daemon.rs:876). Add a per-FrontendView
  `fold_projection_active` flag (editor_core.rs:240, set at attach / cleared
  at detach); gate ALL command-time visible-line reckoning (motion, paging,
  wheel, click, auto-scroll) on it. Render-time clamps are already
  grid-path-only. New Q#FD21 + simultaneous TUI+semantic acceptance.
- F2 (major): render maps must be per WINDOW, not per frame — paint_frame
  and the presence pass iterate windows with distinct buffer_ids
  (editor.rs:2922, overlay_paint.rs:124). Specify one map per rendered
  nonterminal window (keyed on window buffer_id + TextView); peer presence
  uses the recipient window's map. New split-of-different-buffers acceptance.
- F3 (moderate): hidden positions need COLUMN projection, not only row
  clamping. Add `visible_position_of(pos)` -> outermost fold's range.start
  (end of visible head line, Stage 1's point-move target) for local/peer
  carets and selection endpoints; hidden interiors still drop. New
  hidden-cursor-column-differs acceptance.
- Nits: fix the Viewport<'a> typo; state build cost honestly as O(folds)
  with a byte->line lookup per fold (B4).

PR #147 (the #142 housekeeping) confirmed clean by the reviewer, no findings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 16:55:25 -04:00
Levi Neuwirth e221f131f0 docs(folding): Stage 2 framing rev 2 — address review round 1
Round 1's five findings + two rulings, all verified against c49a8c7:

- F1 (major): nested folds. `head_of`(innermost) could clamp onto a
  still-hidden inner head. Replace with `visible_head_of` (outermost
  visible head); `view_top` clamps BACKWARD to the head, not forward
  past the fold; relative numbers anchor on the clamped visible cursor.
- F2 (major): the consumer census was incomplete. Add the full §2.2
  table — local selection (editor.rs:3241), peer presence
  (overlay_paint.rs:159, after paint_frame), mode-line indicator
  (editor.rs:3803), style/search/completion overlays — and make TUI
  peer-presence fold behavior explicit scope.
- F3 (major): line numbers default Off => gutter_w==0 => no sign cell.
  Make the fold glyph conditional: off => ellipsis only; on => sign
  cell with diagnostic priority. Dedicated column (unconditional) named
  as a deferred layout change.
- F4 (major): a frame-pinned map can't serve command-time motion, and
  Viewport is Copy. Reframe as one derivation primitive with per-phase
  short-lived instances (render via Option<&VisibleLineMap> on a
  lifetime-bearing Viewport, preserving Copy; after-frame direct;
  command-time fresh); home usable from EditorCore.
- F5 (moderate): key the Lua-path widening on InteractiveCommandOrigin
  (editor.rs:53), hook the common run_buffer_edit (not only
  run_managed_edit) so bypass_intercept edits don't escape, require the
  target to be the invoking frontend's active-window buffer, and
  explicitly DEFER undo/redo unfold.

Rulings: Q#FD17 include (normalize a hidden cursor to the visible head
before stepping); #142 housekeeping stays a separate docs PR.

Acceptance expanded to pin nested-fold/shared-cursor, local selection,
peer presence, an ordinary overlay across a fold, completion anchoring,
the scroll indicator, and both gutter-off/gutter-on fold-marker cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 16:08:22 -04:00
Levi Neuwirth 59410c004d docs(folding): frame Stage 2 — grid (daemon) collapse (rev 1)
Reframe Arc 6 folding Stage 2 in detail off canonical main @ c49a8c7
(Stage 1 / #142 merged), per the parent framing's §8/§14. Continues the
Q#FD scheme from Q#FD12.

Stage 2 makes the daemon grid renderer fold-aware: collapse hidden lines,
head-line ellipsis + gutter fold glyph, fold-aware line numbers
(visible-line relative distance), diagnostic-sign clamp-to-head, caret
clamp, visible-line viewport/scroll accounting, and the interactive-Lua
unfold widening (yank/query-replace/comment). No wire schema or protocol
change — FoldState production (Stage 1) is untouched; the GPU path is
Stage 3.

Scout findings that shaped the framing:
- The TUI has NO non-identity source-line->display-row map today; the
  identity `view_top + row` is baked into ~7 sites. Folding is the first
  such map, so Stage 2's spine is one shared per-frame visible-line map
  (Q#FD12) that the render loop and every view_top-arithmetic site
  consult; collapse lives in TextView::render, not the diff shell.
- Correcting the parent's premise: yank + query-replace are
  apply_active_edit callers (local), not Lua-mutator callers; only
  comment-toggle/yank-pop take the Lua path (shared with the
  remote/optimistic-CRDT apply that stays deferred to Stage 3). The
  widening hooks the local funnels only (Q#FD19).

One open scope fork flagged for the user: Q#FD17 (fold-aware vertical
line-motion vs render-time caret clamp only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 15:41:11 -04:00