Record the firmware boot-read (serde_json builds for xtensa) and the just-init catalog as delivered, and replace the proposed French catalog with the finalised 17-snippet English set (three groups). Note the →/≠ base-font caveat and the no-clobber seeding guard.
7.2 KiB
v0.6 — Markdown affordances
Part of the Typoena macro plan. Requirements and targets: qfd.md. Load-bearing decisions: adr.md.
Status: render affordances done early. The snippet engine (tab-stop core,
inline Tab-expansion, hint-on-pause, $ palette) and the > command-palette
generalisation are done in core, host-tested (187 editor tests); the
remaining work is the firmware boot-read + just init catalog (slice 5, the
on-device gate). Snippets are net-new scope, added 2026-07-08; reshaped
2026-07-12 from a hard-coded table into a git-synced, Zed-compatible library with
a $ palette launcher — see typoena-snippets.md for the
file format.
- Heading lines bolded in render (faux-bold double-strike)
- List continuation on Enter inside
-/1.(with empty-item exit) - Soft-wrap at word boundaries
Snippets
Trigger-driven text expansion for Markdown authoring (Zed-inspired, but no
completion popup: e-ink's ~630 ms refresh rules out a live filtering menu, and
it fights the distraction-free premise). The library is a git-synced,
Zed-compatible JSON file — full file-format reference in
typoena-snippets.md. This section is the editor
behaviour.
- The tab-stop engine — the shared core both surfaces drive. A body is
literal text plus numbered stops
$1 … $nand a final$0; on insertion the caret lands on$1(or the end), in Insert. Tab advances to the next stop, forward only (no Shift-Tab); pending stops sit after the caret and shift with edits there. The session auto-aborts on Esc, a mode change, or a motion that leaves the stops.${n:label}parses to a bare$n(the label is stripped — no selection model to fill); no dynamic values (no RTC, so nodate). - Inline Tab-expansion (Insert mode). If the word immediately before the
caret matches a snippet prefix, Tab expands it and starts the tab-stop
session; otherwise Tab inserts spaces as today. A check in the Insert
handler alongside the existing
list_markertransform (expand_snippet(word) -> Option<Snippet>). Tab already arrives asKey::Char('\t'), so no new key event. - Hint-on-pause. On the typing pause (same throttle as the word-count /
cursor refresh — never a per-keystroke repaint), if the word before the
caret is a prefix, the right side panel shows a quiet hint (
» name, on the row above the mode line, sharing the slot with theNO KBDflag — the two never co-occur since the hint means you're typing). The panel is ~15 cols, so the hint is the snippet name, not the whole body — the full preview is the$palette's job. Snapshotted inrefresh_statsso it rides the pause, and the firmware's Insert-pause repaint already carries it (no firmware change). Latin-9 has no↹glyph, hence the»marker. $palette (browse + insert).Cmd-Pthen$switches the palette to the snippet list (the same sigil mechanism as>). Fuzzy-matches name / prefix / description; Enter inserts the body at the caret and starts the tab-stop session. Lists all snippets — the fuzzy filter handles clutter, so there's no hidden "inline-only vs palette-only" split. Rows readName [prefix], so browsing also teaches the inline trigger.- Boot wiring. The host reads
/sd/repo/.typoena.snippets.jsonat boot and callsEditor::set_snippets(mirroringset_prefs); a missing or malformed file is non-fatal (no snippets, editor runs). Parse lives in the host-testableeditorcrate viaserde_json— the one new dependency, confirmed to build for xtensa (cargo check, firmware 0.6.0). On-device smoke-test still pending.
The palette, generalised (Cmd-P · > · $) — done in core
v0.5 shipped Cmd-P = files and > = a five-entry settings list (save_on_idle,
format_on_save, line_numbers toggles + theme/auto_sync rotations). v0.6
makes the sigils a clean split by verb, and the empty-palette placeholder legends
them: Go to file · > settings · $ snippets.
- bare
Cmd-P→ navigate: go to file (unchanged). >→ act on the editor — the command palette, a real action registry (thePALETTE_CMDSlist, actions first then settings). The pref toggles are just its stateful entries, not a special section. Dispatch is byPaletteCmd::kind: a toggle flips and the list stays open; a one-shot (format,publish— the latter sharesrun_publishwith:sync) runs and closes; a parameterised command (new file...) morphs the palette into a second input step (the box becomes a filename prompt → Enter creates it, scope read from arepo//local/prefix as:enewdoes; backspacing past the start steps back to the>list). This retired:e— bareCmd-Pcovers file-opening; dotfiles can get a dedicated> edit ...command if/when wanted.$→ insert content — the snippet launcher above.
Labels avoid …/↹ — the palette/panel fonts are ISO-8859-15, which has neither
glyph — so new file... uses ASCII dots and the pause hint leads with ».
First-time setup — snippet catalog (just init) — done
just init seeds the two
git-tracked config files into repo/ (so they commit + sync on the device's
first :sync), writing only a file that is absent so a re-init never
clobbers a synced library: a starter .typoena.toml (the five
keys at their defaults) and a .typoena.snippets.json
assembled from a curated catalog (firmware/snippets-catalog/, jq-merged).
The catalog is grouped and opt-in — you pick the groups (each [Y/n], all-yes on
a non-interactive run) rather than getting one writer's whole personal set. Not
every Zed snippet is worth proposing: the Slidev/blog-pipeline ones (@[youtube],
<v-clicks>, frontmatter, mermaid) and hyper-specific personal ones are left out,
since a distraction-free prose appliance can't render them and you'd never miss
them. Prefixes are English (except edanso, the mnemonic for œ), bodies
translated from the source Zed snippets. Three groups, 17 snippets:
- Symbols (inline, the keyboard can't type them):
arrow→→,neq→≠,times→×,middot→·,deg→°,euro→€,edanso→œ(dead keys in v0.2.5 cover accents, not these). Caveat:→(U+2192) and≠(U+2260) are outside ISO-8859-15, so they store correctly and sync but render as a missing-glyph box on the device panel until the font is extended; the other five are Latin-9 and draw fine. Kept deliberately. - Structure:
todo→- [ ],link→[$1]($2)$0,img→$0,table(2-col),code(fenced block).img/codeare net-new. - Prose / PKM templates (
${n:label}stripped to$n):booknotes,reference(the English reference block —refanglfolded in),bias,capture,standard. (5w1hdropped.)