docs(roadmap): sync marks to actual core progress

The editor core runs 2-3 versions ahead of shippable device releases (no
release has shipped; v0.1's hardware gate is still open). Mark done/partial
items across v0.1-v0.7 with [x]/[~], record what landed early (View mode,
d/c operators + text objects, :fmt), and the v0.4 decision to move View off
v/V so Visual can take them.
This commit is contained in:
Julien Calixte
2026-07-07 23:44:46 +02:00
parent b746d6e3f9
commit 77768cc85f

View File

@@ -5,36 +5,57 @@ The macro-plan (Gantt) lives in the [README](../README.md#roadmap); this file
holds the per-version scope. The user-facing requirements and engineering
targets each release feeds into are tracked in [`qfd.md`](qfd.md).
## Status — synced 2026-07-07
The editor **core** (`firmware/src/editor.rs`) has been built 23 versions
ahead of the device **releases**. No release has shipped: v0.1's hardware gate
(SD, splash, wiring the git/save path into the app binary) is still open, even
though v0.2 navigation and most of v0.6 Markdown already run. Version numbers
are unchanged — they track shippable device releases, not core progress.
Marks: `[x]` done in core · `[~]` partially done · `[ ]` not started. An
inline `(✓)` marks the done half of a split item.
---
## v0.1 — MVP: "it writes, it pushes" — [ ]
## v0.1 — MVP: "it writes, it pushes" — [~]
The minimum thing that justifies the hardware existing. Full design:
[product](v0.1-mvp-product.md) · [technical](v0.1-mvp-technical.md).
- [ ] ESP32-S3 boots, e-ink shows Typoena splash + boot log
- [ ] USB host enumerates the Nuphy, key events reach the editor
- [ ] One hard-coded file (`/sd/repo/notes.md`) opens on boot
- [ ] Insert-only editing (no modes yet), backspace, enter, arrow keys
- [ ] Line wrap, no line numbers yet
- [ ] Save on `Ctrl-S` → SD
- [ ] Wi-Fi credentials + remote URL + PAT + author baked into the binary at
**Status:** core editing + partial refresh run on device. **Blocked** on three
integration items: SD (Spike 3 — awaiting a compatible ≤32 GB card), the boot
splash (Spike 9), and wiring the git/save path into the app binary — today it
lives in the `git_sync` / `sd_fat` spike bins, not `main.rs`.
- [~] ESP32-S3 boots (✓); e-ink shows Typoena splash + boot log — splash pending Spike 9
- [x] USB host enumerates the Nuphy, key events reach the editor (Spike 4)
- [ ] One hard-coded file (`/sd/repo/notes.md`) opens on boot — SD spike-only, not in `main.rs`
- [x] Insert-only editing, backspace, enter, arrow keys — modal editor overshot this early (see v0.2)
- [x] Line wrap, no line numbers yet — soft-wrap done early (see v0.6)
- [ ] Save on `Ctrl-S` → SD — SD blocked, not wired to `main.rs`
- [x] Wi-Fi credentials + remote URL + PAT + author baked into the binary at
build time via env vars (no NVS, no on-device provisioning UI in v0.1)
- [ ] `Ctrl-G` runs: `git add .` → commit with an ISO-8601 timestamp message →
- [~] `Ctrl-G` runs: `git add .` → commit with an ISO-8601 timestamp message →
`git push`; on push failure, `git pull --no-edit` then retry the push
(no-op short-circuit when nothing is staged). PAT from first-run setup.
- [ ] Partial refresh on edits; full refresh on save
(no-op short-circuit when nothing is staged). Proven on device in the
`git_sync` spike (✓); not yet wired to the editor.
- [~] Partial refresh on edits (✓ Spike 5); full refresh on save — save not wired yet
Out of scope: Vim, palette, multiple files, branches, conflict handling.
## v0.2 — Vim navigation — [ ]
## v0.2 — Vim navigation — [~]
- [ ] Mode state machine (Normal / Insert), mode indicator in the side panel
- [ ] Movement: `h j k l`, `w b e`, `0 $`, `gg G`, `Ctrl-d Ctrl-u`
- [ ] `i a o O A` to enter Insert
- [ ] `Esc` returns to Normal
**Status:** navigation done in core; remaining = `Ctrl-d/u`, the line-number
gutter, and the UTF-8 buffer. Shipped early beyond scope: a read-only **View**
mode and the full `d`/`c` operator + text-object grammar (see v0.3 / v0.4).
- [x] Mode state machine (Normal / Insert / View), mode indicator in the status strip
- [~] Movement: `h j k l`, `w b e`, `0 $`, `gg G` (✓); `Ctrl-d Ctrl-u` remain
- [x] `i a o O A` to enter Insert
- [x] `Esc` returns to Normal
- [ ] Line numbers in the left gutter: relative in Normal mode (current line
shown as its absolute number), absolute in Insert mode
shown as its absolute number), absolute in Insert mode — Spike 13 first
- [ ] Groundwork — UTF-8-correct buffer: caret motions and edits step by
character, not byte (drop the ASCII == byte-offset assumption in
`editor.rs`), so every motion added here and later stays correct once
@@ -44,6 +65,8 @@ Out of scope: Vim, palette, multiple files, branches, conflict handling.
## v0.2.5 — International input — [ ]
**Status:** not started (depends on the v0.2 UTF-8-correct buffer).
A small focused release between navigation and editing. US-International
dead-key accent composition, resolved in the keyboard layer (`usb_kbd.rs`) so
the editor still receives a single `Key::Char`. Builds on the v0.2
@@ -58,19 +81,40 @@ UTF-8-correct buffer and the ISO-8859-15 render font.
accent as its literal first
- [ ] Pending-accent indicator in the side-panel status strip
## v0.3 — Vim editing — [ ]
## v0.3 — Vim editing — [~]
- [ ] `x dd yy p P`, `dw dd d$`, repeat with `.`
**Status:** deletes and counts done; **yank/paste, undo/redo, and `.` repeat
remain** — there is no register or recorded-op mechanism yet. The `d`/`c`
operator grammar and text objects landed here ahead of schedule (the roadmap
had scheduled only `dd`/`dw`/`d$`).
- [~] `x dd`, `dw dd d$` (✓); `yy p P` and repeat with `.` remain (need a register / recorded op)
- [ ] Undo / redo (`u`, `Ctrl-r`) — bounded history in PSRAM
- [ ] Numeric prefixes (`3dd`, `5j`)
- [x] Numeric prefixes (`3dd`, `5j`)
- [x] Ahead of schedule: `c` change operator + text objects
(`ciw`, `di(`, `ca"`, … — inner/around, nesting-aware)
## v0.4 — Visual mode + ex commands — [ ]
## v0.4 — Visual mode + ex commands — [~]
**Status:** the `:` command-line mechanism is built (Command mode + status-strip
echo), but only `:fmt` exists — `:w :q :wq :e` remain. Visual mode is not
started.
**DECISION (2026-07-07):** `v`/`V` = **Visual** selection (vim-standard). The
read-only **View** (reading/scroll) mode currently bound to `v`/`V` moves off
those keys and gets its own trigger (exact key TBD when Visual lands). View mode
stays — it just frees `v`/`V` for Visual.
- [ ] Visual char (`v`) and line (`V`) modes, `y d c` on selections
- [ ] `:` command line: `:w :q :wq :e <path>`
- [~] `:` command line: `:w :q :wq :e <path>` (mechanism ✓; these commands remain)
- [x] Ahead of schedule / unscheduled: `:fmt` Markdown formatter
(table alignment, blank-line collapse, trailing-whitespace strip)
## v0.5 — File palette + multi-file — [ ]
**Status:** not started (Spikes 11 + 14 retire the panel-mechanism and
buffer-lifecycle risk first).
- [ ] `Ctrl-P` opens fuzzy file palette over **both** `/sd/repo/` and
`/sd/local/`, with a scope marker (e.g. `[git]` / `[local]`) per result
- [ ] Open, switch, close buffers (keep ≤ 3 in memory)
@@ -84,15 +128,19 @@ UTF-8-correct buffer and the ISO-8859-15 render font.
more than one dirty Tracked file (e.g. `"publishing 3 files: abc1234"`),
so workspace-scoped behaviour stays visible to the user
## v0.6 — Markdown affordances — [ ]
## v0.6 — Markdown affordances — [~]
- [ ] Heading lines bolded in render
- [ ] List continuation on Enter inside `- ` / `1. `
- [ ] Soft-wrap at word boundaries
**Status:** done early — only the 80-col ruler remains.
- [x] Heading lines bolded in render (faux-bold double-strike)
- [x] List continuation on Enter inside `- ` / `1. ` (with empty-item exit)
- [x] Soft-wrap at word boundaries
- [ ] Optional column ruler at 80
## v0.7 — Search + better git — [ ]
**Status:** not started.
- [ ] `/` forward search, `n N`
- [ ] `:Gpull` (fetch + fast-forward only; refuse on conflict and surface it)