Files
typewriter/docs/v0.7-search-and-git.md
Julien Calixte a941ae39b3 feat(sync): :gl pull — fetch + fast-forward only on the git thread
The git channel now carries GitRequest::{Publish,Pull} with a shared
ensure_online preamble (Wi-Fi/clock/TLS once per session). pull_once
fetches origin — refreshing the tracking ref so the radio-free
up-to-date check stays honest — and maps four shapes: up to date,
LocalAhead (stranded commit, :sync's job), clean fast-forward,
Diverged (refused; no merge on the device). The fast-forward is a SAFE
checkout then ref move: it refuses to overwrite content that differs
from HEAD, the belt under the UI gate that refuses :gl while the dirty
journal is non-empty. A RAM-dirty buffer doesn't gate — its edits win
(last-writer-wins, like the reconcile).

After a pull the UI drops clean parked buffers, re-reads the clean
active buffer in place (Editor::refresh_active), and re-walks the
palette list. Firmware 0.6.0 -> 0.7.0. On-device verification pending.
2026-07-14 01:10:00 +02:00

3.7 KiB

v0.7 — Search + better git

Part of the Typoena macro plan. Requirements and targets: qfd.md. Load-bearing decisions: adr.md.

Status: / search + n N done in core (2026-07-13, host-tested — 207 editor tests). :gl pull BUILT end-to-end 2026-07-14 (firmware 0.7.0, compiles clean; editor refresh hooks host-tested, 209 tests) — on-device verification pending (needs Wi-Fi + a remote that moved).

  • / forward search, n N — done in core 2026-07-13 (host-tested). Literal, case-sensitive substring (no regex on-device, no smartcase surprises); / reuses the : command line's editing with a / prompt (one command-line mode, as in vim), and the jump happens on Enter only — no incremental caret-chasing, for the same e-ink-refresh reason snippets have no completion popup. Wraps around with a "wrapped" notice; "not found: pat" leaves the caret alone; a bare /+Enter repeats the last pattern, which is editor-global (survives buffer switches, like vim's search register). n/N are motions (counts work, Visual extends over them); deliberately not operator targets (dn out of scope).
  • [~] :gl — pull: fetch + fast-forward only, refuse on divergence and surface it (renamed from the planned :Gpull). Editor command + Effect::Pull done 2026-07-11; the git-thread fetch/fast-forward is BUILT 2026-07-14 — on-device verification pending. How it works:
    • The git thread takes a GitRequest::Pull on the same channel as publish (shared ensure_online Wi-Fi/clock/TLS preamble). pull_once fetches origin (the fetch also refreshes the remote-tracking ref, keeping publish's radio-free up-to-date check honest), then maps the four shapes: up to date / LocalAhead (stranded commit — :sync's job) / clean fast-forward / Diverged (refused, no merge on the device).
    • The fast-forward is checkout-then-ref-move with a SAFE checkout: it refuses to overwrite a file whose content differs from HEAD (belt; the UI gate is the braces). FAT caveat: the splice never updates the index, so SAFE re-hashes each file the pull changes — O(changed), never O(tree).
    • UI gate: :gl is refused while the dirty journal is non-empty ("unsynced changes - :sync first") — an unpublished save would fight the checkout, and sync-then-pull is the single-writer appliance's natural order. A RAM-dirty (never-saved) buffer does not gate: its edits simply win over the pulled state (last-writer-wins, like the reconcile).
    • After a Pulled outcome the UI drops clean parked buffers (next switch re-reads the disk), re-reads the clean active buffer in place (Editor::refresh_active — boot posture, undo cleared), keeps a RAM-dirty active buffer untouched, and re-walks the palette file list. Snackbar: pulled <oid> / up to date / ahead - :sync to publish / diverged - resolve on a computer / pull: <reason>.

Sync performance — inherited from the real-repo-sync kaizen (closed 2026-07-13 at 24.1 s end-to-end; target ≤ ~10 s):

  • Close the publish gap: 19.8 s today — the splice's 5.0 s and the ~7 s of repo-open/negotiation overhead are the next curves (tradeoff analysis).
  • Instrument the residual ~360 ms/loose-write (suspect: FAT directory-op cost in the freshen/refresh path) — one sd_bench + p_mmap-miss logging pass.
  • The images-off-card lever (notes/git-sync-images-and-repo-size.md) composes with the splice — decide whether to take it here.