summaryrefslogtreecommitdiff
path: root/transactions.txt
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-07 09:48:05 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commit9da20917b6f4cf98fd9b5c2c0a904e4f6a8380a9 (patch)
treec7c8c4d1126def565eb0b1d20ad29782eb49c5e7 /transactions.txt
parentb2cdd8ee719961b2f037f20bf0f88fad94ca73b4 (diff)
downloadpardes-9da20917b6f4cf98fd9b5c2c0a904e4f6a8380a9.tar.gz
pardes-9da20917b6f4cf98fd9b5c2c0a904e4f6a8380a9.zip
helix diff testing and feature parity
Diffstat (limited to 'transactions.txt')
-rw-r--r--transactions.txt59
1 files changed, 59 insertions, 0 deletions
diff --git a/transactions.txt b/transactions.txt
new file mode 100644
index 00000000..b1233d3d
--- /dev/null
+++ b/transactions.txt
@@ -0,0 +1,59 @@
+Selection anchors through insert-mode edits, and the transaction model
+=======================================================================
+
+The one place the helix differential suite shows a real structural gap
+(waiver "wiX-edit-drops-sel" in test/hxcases/waivers.jsonl): helix keeps a
+selection ALIVE across insert mode, pardes drops it on the first edit.
+
+What helix does
+---------------
+A selection doesn't die when you enter insert mode. Every edit is a
+Transaction — a structured delta (retain N, insert "...", delete N) — and
+all stored positions are MAPPED through it, the selection anchor included.
+Insert a char before the anchor and it slides right by one; delete a line
+above it and its row shifts up. Esc back to normal mode and the old
+selection is still there, coordinates adjusted to cover the same logical
+text.
+
+Example ("alpha beta" + keys w i X <esc>):
+ after w: anchor (0,0), cursor on the space (0,5), "alpha " selected
+ i, type X: buffer is "Xalpha beta"
+ after esc: helix — anchor (0,1), selection still spans "alpha " (remapped)
+ pardes — selection gone, anchor == cursor
+Final text, cursor, and mode agree on both sides; only the anchor differs.
+
+What pardes does today
+----------------------
+No transaction layer. handleInsert mutates the buffer directly at ~23
+distinct sites (char inserts, newline, backspace incl. the line-join case,
+Ctrl-w/Alt-d word kills, Ctrl-u/Ctrl-k line kills, multi-line paste, and
+the terminal run-splice variants). Keeping the anchor alive would mean
+hand-written row/col shift arithmetic at every one of those sites — 23
+error-prone edit paths to maintain for state nothing reads: d/c/y take a
+fresh selection from the next motion, and the acme Enter/Tab chords only
+act on EXPLICIT selections (v/x/n/N), which never enter insert mode. Hence
+the waiver instead of a fix.
+
+Why we might adopt the transaction model anyway
+-----------------------------------------------
+A small transaction layer (edits as deltas + one mapThroughEdit(pos, edit)
+helper applied at each mutation site) would buy, in rough order of value:
+ - "." repeat-last-insert (currently deferred in docs/helix-keys.md for
+ exactly this reason: no edit log to replay)
+ - delta-based undo/redo instead of whole-buffer snapshots (pushUndo
+ dupes f.content per edit op today — fine for small files, O(file) per op)
+ - the waived anchor parity for free (selections survive insert mode,
+ remapped like helix)
+ - any future position-carrying state (marks, jumplist, multiple
+ selections) gets remapping for free instead of per-site arithmetic
+
+Upgrade path, if/when
+---------------------
+1. Define the delta type in modal.zig (pure, unit-testable): a list of
+ (retain, insert, delete) spans, plus mapThroughEdit for a (row,col).
+2. Make the ~23 handleInsert mutation sites EMIT a delta and apply it in
+ one place, instead of splicing content inline.
+3. Undo becomes a log of inverse deltas; "." becomes a replay of the last
+ insert session's deltas; drop the y-anchor waiver and its harness case.
+Adopt only when one of the consumers above is actually wanted — the delta
+layer alone is machinery without a user.