From 93f3a43b3451c417c98c5672f6054a7faed457af Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Sun, 12 Jul 2026 09:02:21 +0200 Subject: [PATCH] docs(prefs): document theme + auto_sync presets, override v0.5 deferral Reference doc gains a theme key, an Options column, and the e-paper dark-mode ghosting caveat. The v0.5 spec gets an amendment note superseding the two reversed "decide-before-build" calls (auto_sync now a set-ahead palette command; theme shipped early) without rewriting the verified-on-device history; macroplan updated to match. --- docs/macroplan.md | 7 +-- docs/typoena-toml.md | 77 +++++++++++++++++++---------- docs/v0.5-palette-and-multi-file.md | 37 ++++++++++++-- 3 files changed, 90 insertions(+), 31 deletions(-) diff --git a/docs/macroplan.md b/docs/macroplan.md index 8b8d888..1afb53c 100644 --- a/docs/macroplan.md +++ b/docs/macroplan.md @@ -55,7 +55,7 @@ name = "v0.5 palette + multi-file" start = 2026-09-07 original = 2026-09-28 delivered = 2026-07-12 -learning = "Delivered 2026-07-12, well ahead of the 2026-09-28 baseline, and fully on-device confirmed. Four slices: the drained Effect queue + parked-buffer LRU foundation; the Cmd-P fuzzy file palette (Spike 11 — no ghosting on the transient panel); :enew + file delete (Spike 14 caught that add_all alone doesn't stage a deletion on this libgit2 — fixed with update_all, i.e. git add -A); and the git-tracked .typoena.toml prefs with a stay-open palette `>` command mode + :settings. Both directions of the prefs loop are proven on hardware — boot-read (byte-exact parse) and on-device palette edit (a device publish flipped line_numbers on origin). Three decide-before-build calls: the idle auto-save is unformatted, and both the per-device auto_sync override and the `> auto sync` command are deferred to v0.7 where auto_sync gains behaviour. Descoped from v0.5 (not the four slices): explicit buffer close, the grey-Publish-in-Local panel cue, and the multi-file publish count." +learning = "Delivered 2026-07-12, well ahead of the 2026-09-28 baseline, and fully on-device confirmed. Four slices: the drained Effect queue + parked-buffer LRU foundation; the Cmd-P fuzzy file palette (Spike 11 — no ghosting on the transient panel); :enew + file delete (Spike 14 caught that add_all alone doesn't stage a deletion on this libgit2 — fixed with update_all, i.e. git add -A); and the git-tracked .typoena.toml prefs with a stay-open palette `>` command mode + :settings. Both directions of the prefs loop are proven on hardware — boot-read (byte-exact parse) and on-device palette edit (a device publish flipped line_numbers on origin). Three decide-before-build calls: the idle auto-save is unformatted, and both the per-device auto_sync override and the `> auto sync` command are deferred to v0.7 where auto_sync gains behaviour. Amended 2026-07-12: a light/dark `theme` key and a set-ahead `> auto sync` preset command (2m/5m/10m/15m/30m) were added on top — the palette generalised so Enter rotates any pref to its next value (a bool is the two-option case); auto_sync is still read by nothing until v0.7. Descoped from v0.5 (not the four slices): explicit buffer close, the grey-Publish-in-Local panel cue, and the multi-file publish count." [[feature]] name = "v0.6 markdown" @@ -202,8 +202,9 @@ reconnect, and on-device provisioning (the first release usable by a non-author) ## v1.0 — Polish — [ ] -≤ 3 s boot, runtime-switchable fonts and light/dark theme, enclosure files, and -a user guide. **Not started.** Detail: [v1.0-polish.md](v1.0-polish.md). +≤ 3 s boot, runtime-switchable fonts, enclosure files, and a user guide +(light/dark theme landed early, in v0.5). **Not started.** Detail: +[v1.0-polish.md](v1.0-polish.md). ## v1.x — Stretch / nice-to-have diff --git a/docs/typoena-toml.md b/docs/typoena-toml.md index 0c674f3..2305f8d 100644 --- a/docs/typoena-toml.md +++ b/docs/typoena-toml.md @@ -1,8 +1,9 @@ # `.typoena.toml` — editor preferences > The git-tracked file that controls how the editor behaves — auto-save, -> format-on-save, and the line-number gutter. Hand-editable, or toggled live -> from the `Cmd-P` palette. Landed in **v0.5** (see +> format-on-save, the line-number gutter, and the panel theme. Hand-editable, or +> changed live from the `Cmd-P` palette (booleans flip; the theme and auto-sync +> interval rotate through preset options on **Enter**). Landed in **v0.5** (see > [`macroplan.md`](macroplan.md)). > > **Not to be confused with `/sd/typoena.conf`** — that holds the device @@ -20,8 +21,8 @@ It lives inside the Tracked repo (`/sd/repo`), so it is **committed and pushed** like any note — which means the preferences **sync to every device** that clones the repo. That is deliberate: your editor behaviour follows you. (A per-device override for the one genuinely device-specific key, `auto_sync`, may layer on top -later via `typoena.conf` — deferred until `auto_sync` actually does something in -v0.7. See the [auto_sync](#auto_sync) note.) +later via `typoena.conf` — worth it only once `auto_sync` actually does something +in v0.7. See the [auto_sync](#auto_sync) note.) The file is read **once at boot**, before the first screen is drawn (so `line_numbers` shapes the opening frame). A **missing, empty, or partial file is @@ -30,21 +31,27 @@ works with no config present. ## Keys -| Key | Type | Default | Effect | -| --- | --- | --- | --- | -| `save_on_idle` | bool | `true` | Auto-save the current buffer on the idle typing-pause, so `:w` is optional. | -| `format_on_save` | bool | `true` | Run `:fmt` on the buffer before an explicit `:w`/`:sync`. | -| `line_numbers` | bool | `true` | Show the absolute line-number gutter. Off reclaims its columns for text. | -| `auto_sync` | string | `"10m"` | Max-staleness cap for opportunistic auto-publish. **Schema only in v0.5 — no behaviour yet.** | +| Key | Type | Default | Options | Effect | +| --- | --- | --- | --- | --- | +| `save_on_idle` | bool | `true` | `true` / `false` | Auto-save the current buffer on the idle typing-pause, so `:w` is optional. | +| `format_on_save` | bool | `true` | `true` / `false` | Run `:fmt` on the buffer before an explicit `:w`/`:sync`. | +| `line_numbers` | bool | `true` | `true` / `false` | Show the absolute line-number gutter. Off reclaims its columns for text. | +| `theme` | string | `"light"` | `light` / `dark` | Panel colour polarity. `dark` inverts the whole frame to white-on-black. | +| `auto_sync` | string | `"10m"` | `2m` / `5m` / `10m` / `15m` / `30m` | Max-staleness cap for opportunistic auto-publish. **Value only — no behaviour yet** (rides v0.7). | + +The **Options** column is what the palette rotates through on **Enter**; a +boolean is just the two-option case. Hand-editing a string key can still set any +value — the palette only cycles the presets. ### Example ```toml # Typoena editor preferences — hand-editable, git-tracked. -# Edit here, or toggle live from the Cmd-P palette (type `>`). +# Edit here, or change live from the Cmd-P palette (type `>`). save_on_idle = true format_on_save = true line_numbers = true +theme = "light" auto_sync = "10m" ``` @@ -82,14 +89,29 @@ returns the gutter's columns to the text, so prose gets the full writing width. Applied **live** — toggling it from the palette redraws immediately with (or without) the gutter. +### `theme` + +Panel colour polarity: `light` (the native black-ink-on-white-paper) or `dark` +(white-on-black). On the 1-bit e-paper panel this is not a palette swap but a +**whole-frame invert** applied at the very end of the render, so text, selection, +caret, side panel and command palette all flip together and each stays legible. +Any value other than `dark` reads as light. Applied **live** — cycling it from +the palette repaints inverted at once. + +> **On e-paper, `dark` is not free.** Partial refreshes over a mostly-black field +> ghost more than over white, and the panel is tuned for white-background reading. +> It works, but expect a slightly muddier refresh than `light` — verify on-device. + ### `auto_sync` -A duration string (`"10m"`, `"2m"`, `"0"`/empty to disable) that will one day cap -how stale the published copy is allowed to get — an *opportunistic, rate-limited* -push, not a wall-clock timer. **In v0.5 this is schema + default only:** the value -is parsed, preserved through a round-trip, and shown nowhere editable — **nothing -reads it yet.** The periodic push itself rides the better-git work in v0.7 and -must interact with sleep in v0.8. Rationale for the `"10m"` default: +A duration string that will one day cap how stale the published copy is allowed +to get — an *opportunistic, rate-limited* push, not a wall-clock timer. The +palette rotates it through the presets `2m` / `5m` / `10m` / `15m` / `30m` +(hand-editing can still set any string, e.g. `"0"`/empty to disable). **The value +is only stored and displayed in v0.5 — nothing reads it yet:** the periodic push +rides the better-git work in v0.7 and must interact with sleep in v0.8, so +cycling the interval today changes what will be honoured *then*, not now. +Rationale for the `"10m"` default: [`tradeoff-curves/wifi-auto-sync.md`](tradeoff-curves/wifi-auto-sync.md). ## Editing it @@ -104,22 +126,27 @@ Two ways, both landing in the same file: - **`Cmd-P`** then type **`>`** — switches the file palette to the command list (VS Code semantics). - The three boolean prefs appear as toggles carrying their current state: + Every pref appears carrying its current state: ``` > save on idle: on format on save: on line numbers: on + theme: light + auto sync: 10m ``` - `Ctrl-N`/`Ctrl-P` move the selection; **Enter** flips the selected pref, - applies it at once, writes the change back to `.typoena.toml`, and confirms - the new state on the snackbar (e.g. `line numbers: off - saved`). **The list - stays open** so you can flip several prefs in a row; **Esc** (or `Cmd-P`) - closes it. Each change rides the next `:sync` to your other devices. + `Ctrl-N`/`Ctrl-P` move the selection; **Enter** advances the selected pref to + its next value, applies it at once, writes the change back to `.typoena.toml`, + and confirms the new state on the snackbar (e.g. `theme: dark - saved`). A + boolean flips; the theme and auto-sync interval **rotate through their preset + options and wrap** — same key, so the palette is uniformly "press Enter to + change". **The list stays open** so you can change several prefs in a row; + **Esc** (or `Cmd-P`) closes it. Each change rides the next `:sync` to your + other devices. - `auto_sync` is **not** a palette command in v0.5 (it has no behaviour to - drive yet); it returns as a value command in v0.7. + `auto_sync` is a value command now, but has no behaviour to drive until v0.7 — + cycling it sets the interval that the future periodic push will honour. ## Parsing diff --git a/docs/v0.5-palette-and-multi-file.md b/docs/v0.5-palette-and-multi-file.md index 071a753..9320da1 100644 --- a/docs/v0.5-palette-and-multi-file.md +++ b/docs/v0.5-palette-and-multi-file.md @@ -108,6 +108,25 @@ true via a *device*-authored publish (`3c79f38`), proving toggle → `SavePrefs` atomic write → `git add -A` → push — and the `save_on_idle` autosave works on device too. **v0.5 slice 4 fully DONE + on-device confirmed.** +**Amendment 2026-07-12 — non-boolean prefs (`theme`, `auto_sync`).** Two of the +"decide before build" calls above are **superseded**: `auto_sync` is now a live +palette command, and a new `theme` (`light`/`dark`) key ships. The generalising +idea is that a boolean toggle is just the two-option case of *rotate through a +preset list on Enter* — so the palette gains one uniform gesture: **Enter +advances the selected pref to its next value and wraps** (a bool flips; a string +pref cycles its options). `theme` rotates `light`↔`dark` and is applied by a +single whole-frame invert at the end of the render ([`Frame::invert`]), so text, +selection, caret, panel and palette all flip together; `auto_sync` rotates +`2m`/`5m`/`10m`/`15m`/`30m`. Decision (3) — "a value control that changes nothing +readable would be a dead switch" — is knowingly overridden: cycling `auto_sync` +persists and displays the interval, but **still drives no behaviour until v0.7**; +we accept a set-ahead control so the surface is ready and the value syncs now. +Decision (2) (per-device `typoena.conf` override) stays deferred. Kept simple: no +enum machinery — both string prefs share a `next_option(current, &OPTIONS)` +helper, and hand-editing the TOML can still set any value (the palette only +cycles presets; an off-list value snaps to the head on the next Enter). Editor +tests cover the rotate/wrap/snap, the live theme invert, and the round-trip. + **Trailing-newline handling — a saved note ends with a *visible* blank line (commit `d14d9e7`, 2026-07-12; host-tested, on-device gate open).** Two adjustments to how the buffer meets the file. First, format-on-save no longer @@ -186,6 +205,12 @@ one. gutter (built always-on in v0.2). Off reclaims the gutter's columns for text (`gutter_cols()` → 0); the palette `> line numbers: on/off` command toggles it live. **Done 2026-07-12.** + - [x] `theme` (string, default `"light"`; options `light`/`dark`) — panel + colour polarity. `dark` is a single whole-frame invert at the end of the + render (`Frame::invert`), so everything flips together and stays legible. + Palette `> theme` rotates `light`↔`dark` live. **Added 2026-07-12 + (amendment); host-tested, on-device check pending.** Caveat: `dark` + partial-refreshes ghost more on e-paper than `light` — verify on panel. - [ ] `auto_sync` (duration string, default `"10m"`; `"0"` / omitted disables; **min clamp ~`"2m"`** so a palette typo can't drain the battery) — a *max-staleness cap*, not a wall-clock timer: @@ -200,6 +225,9 @@ one. through `Prefs`; **nothing reads the value yet** — the periodic side rides the better-git work (v0.7) and must interact with light / deep sleep (v0.8). Marked `[~]`: parsed and preserved, no behaviour. + **Amended 2026-07-12:** now a palette preset command — Enter rotates it + through `2m`/`5m`/`10m`/`15m`/`30m` (the `~2m` min is baked into the + preset list). Set-ahead only: still read by nothing until v0.7. - [x] Open question RESOLVED (2026-07-12): the per-device sync cadence override (a card-local `typoena.conf` layer over the committed prefs) is **deferred** — `auto_sync` is inert in v0.5, so there is nothing yet to @@ -213,6 +241,9 @@ one. **The list stays open after a toggle** (flip several, Esc/`Cmd-P` closes), and **`:settings` opens it directly** — both added 2026-07-12 as the "change config from the device" surface (chosen over a separate settings modal). - This command list is the discoverable surface later actions (`:fmt`, theme, - font) also register into. **`> auto sync: ` deferred to v0.7** — a - value control that changes nothing readable would be a dead switch. + This command list is the discoverable surface later actions (`:fmt`, font) + also register into. **Amended 2026-07-12:** the palette now also carries the + non-boolean prefs `> theme` (`light`/`dark`, live whole-frame invert) and + `> auto sync` (`2m`..`30m`), both cycled by the same Enter-rotates-to-next + gesture. `auto_sync` is exposed **set-ahead** (no behaviour until v0.7), + knowingly overriding the earlier "dead switch" call.