turbo-editors/turbo-gopublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-go.git
git clone ssh://git@rickub.com/turbo-editors/turbo-go.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

📦 Turbo Go 3d7798b · on main · k33g · 9h ago
2026-08-31-project-settings.md · 40 lines · 4.5 KBmarkdown
Blame HistoryOpen raw

Handoff — 2026-08-31 — project settings, autosave, TOML colouring

State

Ticket 0002 is done and green, on branch feature/project-settings, uncommitted.

A project can keep .turbo-go/settings.toml in its own directory, naming a theme and turning on automatic saving. Options ▸ Create project settings writes a commented one filled in with the theme in use and opens it; Options ▸ Project settings… reopens it. TOML is coloured, so the file reads properly in the editor that reads it.

  • New internal/settings (89.3 %), internal/syntax extended with a Language dimension and a TOML scanner (96.8 %), autosave and the menu items in internal/app (84.3 %, up from 82.8 %).
  • Whole suite green under -race. Quality gate PASS: 0 errors, 0 warnings, 0 smells, complexity 1150.
  • Docs complete in EN and FR — three new pages each, six existing pages updated each. docs/diagrams/packages.drawio re-checked against go list: matches edge for edge.
  • Verified end to end with the real binary in a pty, which is the part worth trusting: the theme really comes from settings.toml, -theme really overrides it, and autosave really writes from the idle timer alone — the editor was killed without ever quitting, so no close-or-quit path could have done it. A control run with no settings file left the file untouched.

Earlier the same day, the terminal work was merged to main by the user as PR #1.

In flight

Nothing. The feature is finished through Phase 8.

Next steps

  1. Commit and open the PR. feature/project-settings already exists on the remote.
  2. Decide whether autosave should be true in the created file. It is false today — see "Open questions" below. This is the one place where I chose and the user has not yet reacted.
  3. Use autosave for a real working session. It is verified but has never been lived with, which is where a save at an unwanted moment would show up.
  4. Decide about tickets 0002 and 0007. Both are implemented, both still state: open.

Open questions / blockers

  • autosave = false in the created file. The request read "dire que les fichiers sont sauvegardés automatiquement", which can be read as "the file records that they are" (→ true) or "the file is where you say so" (→ false). I announced false in the plan, the user said "va au bout du bout" without correcting, so false it is. It is a one-line change in template in internal/settings/create.go plus its test in settings_test.go and two doc pages if that was the wrong read.
  • The menu entries are flat, not a submenu. The request said "un sous-menu"; ui.MenuItem has no Items field and ui.MenuBar has no nesting, so building it would have been an unrequested ui change. Two items sit under Options instead. If real nesting is wanted, that is a ui feature in its own right.
  • .turbo-go/ is not in .gitignore, and that is deliberate — whether a project's theme is a team decision or a personal one is the user's call, not mine. The docs say so in both languages.

Watch out for

  • emit drops empty spans, so patching a span after the fact is unsafe. In internal/syntax/toml.go I set spans[len-1].Start after an emit that had produced nothing, which silently rewrote the previous span into an invalid range. The fix is to pass the start into the function. If you extend the scanner, pass positions in; do not patch them on afterwards.
  • Do not assert on a screen cell while a live shell or process writes to it. Already recorded from the terminal session; it came up again here and the test was written offline instead.
  • A pseudo-terminal echoes what you type. Same trap, third appearance. In the pty smoke tests, the text typed is visible in the captured output whether or not the editor did anything with it — the file on disk is the evidence, not the screen.
  • main.themeName depends on -theme's flag default being "". If someone "tidies" it back to theme.DefaultName, precedence silently breaks: the project's theme would never apply, because the flag would always look as though it had been given. TestThemeNameUsesTheProjectWhenNoFlagWasGiven covers it.
  • saveDueDocuments must stay at the top of the Run loop, beside announceOpenDocuments. Moving the saving into the time.AfterFunc would look tidier and would lose saves: that callback's only safe act is wake, whose PostEvent is allowed to drop.
  • The autosave tests inject a.now. Do not "fix" them to use time.Now and short sleeps — they are fast and deterministic precisely because they do not.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Handoff — 2026-08-31 — project settings, autosave, TOML colouring

## State

**Ticket 0002 is done and green**, on branch `feature/project-settings`, **uncommitted**.

A project can keep `.turbo-go/settings.toml` in its own directory, naming a theme and turning on automatic saving. **Options ▸ Create project settings** writes a commented one filled in with the theme in use and opens it; **Options ▸ Project settings…** reopens it. TOML is coloured, so the file reads properly in the editor that reads it.

- New `internal/settings` (89.3 %), `internal/syntax` extended with a `Language` dimension and a TOML scanner (96.8 %), autosave and the menu items in `internal/app` (84.3 %, up from 82.8 %).
- Whole suite green under `-race`. Quality gate **PASS**: 0 errors, 0 warnings, 0 smells, complexity 1150.
- Docs complete in EN and FR — three new pages each, six existing pages updated each. `docs/diagrams/packages.drawio` re-checked against `go list`: matches edge for edge.
- **Verified end to end with the real binary in a pty**, which is the part worth trusting: the theme really comes from `settings.toml`, `-theme` really overrides it, and autosave really writes from the idle timer alone — the editor was killed without ever quitting, so no close-or-quit path could have done it. A control run with no settings file left the file untouched.

Earlier the same day, the terminal work was merged to `main` by the user as PR #1.

## In flight

Nothing. The feature is finished through Phase 8.

## Next steps

1. **Commit and open the PR.** `feature/project-settings` already exists on the remote.
2. **Decide whether `autosave` should be `true` in the created file.** It is `false` today — see "Open questions" below. This is the one place where I chose and the user has not yet reacted.
3. **Use autosave for a real working session.** It is verified but has never been lived with, which is where a save at an unwanted moment would show up.
4. **Decide about tickets 0002 and 0007.** Both are implemented, both still `state: open`.

## Open questions / blockers

- **`autosave = false` in the created file.** The request read "dire que les fichiers sont sauvegardés automatiquement", which can be read as "the file records that they are" (→ `true`) or "the file is where you say so" (→ `false`). I announced `false` in the plan, the user said "va au bout du bout" without correcting, so `false` it is. It is a one-line change in `template` in `internal/settings/create.go` plus its test in `settings_test.go` and two doc pages if that was the wrong read.
- **The menu entries are flat, not a submenu.** The request said "un sous-menu"; `ui.MenuItem` has no `Items` field and `ui.MenuBar` has no nesting, so building it would have been an unrequested `ui` change. Two items sit under Options instead. If real nesting is wanted, that is a `ui` feature in its own right.
- **`.turbo-go/` is not in `.gitignore`, and that is deliberate** — whether a project's theme is a team decision or a personal one is the user's call, not mine. The docs say so in both languages.

## Watch out for

- **`emit` drops empty spans, so patching a span after the fact is unsafe.** In `internal/syntax/toml.go` I set `spans[len-1].Start` after an emit that had produced nothing, which silently rewrote the *previous* span into an invalid range. The fix is to pass the start into the function. If you extend the scanner, pass positions in; do not patch them on afterwards.
- **Do not assert on a screen cell while a live shell or process writes to it.** Already recorded from the terminal session; it came up again here and the test was written offline instead.
- **A pseudo-terminal echoes what you type.** Same trap, third appearance. In the pty smoke tests, the text typed is visible in the captured output whether or not the editor did anything with it — the file on disk is the evidence, not the screen.
- **`main.themeName` depends on `-theme`'s flag default being `""`.** If someone "tidies" it back to `theme.DefaultName`, precedence silently breaks: the project's theme would never apply, because the flag would always look as though it had been given. `TestThemeNameUsesTheProjectWhenNoFlagWasGiven` covers it.
- **`saveDueDocuments` must stay at the top of the `Run` loop**, beside `announceOpenDocuments`. Moving the saving into the `time.AfterFunc` would look tidier and would lose saves: that callback's only safe act is `wake`, whose `PostEvent` is allowed to drop.
- **The autosave tests inject `a.now`.** Do not "fix" them to use `time.Now` and short sleeps — they are fast and deterministic precisely because they do not.