| 📦 Turbo Go 3d7798b k33g 12h ago | 1 | # Handoff — 2026-08-30 — initial build of the editor |
| 2 | |
| 3 | ## State |
| 4 | |
| 5 | The editor is **finished and working** against the original request: Turbo C-style interface, Go syntax colouring, themes, and gopls completion. |
| 6 | |
| 7 | - `make build` produces `bin/turbo-go`; `make test` is green across every package; the quality gate passes with zero smells. |
| 8 | - The LSP client has been driven against a real gopls 0.23.0 and got `strings.Contains` back from a completion at `strings.`. |
| 9 | - Documentation is complete in English and French, and every package has its own `README.md`. |
| 10 | |
| 11 | Nothing is half-written. There is no work in flight. |
| 12 | |
| 13 | ## The one thing to do before anything else |
| 14 | |
| 15 | **Run it in a real terminal.** |
| 16 | |
| 17 | Every visual claim in this repository comes from `tcell.SimulationScreen`. It is a real `Screen` and it exercises the real drawing code, but it is not a TTY. What has *not* been observed on an actual terminal emulator: |
| 18 | |
| 19 | - whether the 24-bit colours in `turbo-dark` and `borland-light` look as intended, and whether `turbo-classic` degrades correctly on a 16-colour terminal |
| 20 | - whether mouse reporting works — window dragging, corner resizing, click-to-place-cursor |
| 21 | - whether `Alt`-letter reaches the program, or is eaten by the terminal emulator (this varies a lot; if it is, `F10` plus arrows is the fallback and the docs already say so) |
| 22 | - whether resizing the window mid-session redraws cleanly |
| 23 | |
| 24 | ```bash |
| 25 | make build && ./bin/turbo-go main.go |
| 26 | ``` |
| 27 | |
| 28 | If something is wrong there, it is almost certainly in `internal/ui/painter.go` or in how `main.go` sets the screen up — not in the widgets, which are well covered. |
| 29 | |
| 30 | ## Next steps, in the order I would take them |
| 31 | |
| 32 | 1. **Real-terminal pass** (above). Everything else is speculative until this is done. |
| 33 | 2. **Show diagnostics where the error is.** `Language.Diagnostics(path)` already holds them per file; the status bar shows only the first error. A coloured marker in the gutter, or the offending span underlined, would use what is already there. The theme keys `diagnostic.error/warning/info` exist and are currently unused by anything that draws. |
| 34 | 3. **CI.** There is none. `make check` plus the quality report is the whole gate and it runs by hand. |
| 35 | 4. **Try it on macOS and Windows.** `lsp.PathToURI` has a drive-letter path and `theme.UserDir` uses `os.UserConfigDir`; neither has ever run outside Linux. |
| 36 | 5. **Profile a large file.** The syntax cache re-scans on revision change, not on redraw, so scrolling should be free — but `buffer.Text()` rebuilds the whole string on every scan, and on a 50 000-line file that may well be the thing that hurts. |
| 37 | |
| 38 | ## Open questions / blockers |
| 39 | |
| 40 | - **`.tickets/0001-specifications.yaml` is an empty issue** created before this work. It was never filled in, and I did not touch it. Worth either writing up or deleting. |
| 41 | - **No licence header policy.** `LICENSE` exists; no source file carries a header. Fine either way, but decide before the first outside contribution. |
| 42 | - **`kits/` is untracked and excluded from qlty.** If it is meant to be committed, the exclusion comment in `.qlty/qlty.toml` explains what it hides; if it is not, `.gitignore` would be the more honest place to put it. |
| 43 | |
| 44 | ## Watch out for |
| 45 | |
| 46 | - **LSP columns are UTF-16, editor columns are runes.** `RuneToUTF16` / `UTF16ToRune` sit at the boundary. On ASCII the two agree, so a mistake here passes every test until a file has an accent in it. There is a test using a musical clef precisely because it needs a surrogate pair. |
| 47 | - **gopls waits for its client to answer `workspace/configuration`.** Ignore server-to-client requests and initialisation hangs with no error at all. `Client.handleRequest` is what stops that. |
| 48 | - **Measure screen widths in runes, never bytes.** `len("[■]")` is 5; the box is 3 columns. This produced a real off-by-two in the window close box. |
| 49 | - **In a dialog, the focused control must see the arrows before the focus ring does.** Getting this backwards makes every list box unusable by keyboard. Two tests in `internal/ui/dialog_test.go` pin it. |
| 50 | - **`Painter.Sub` takes absolute screen coordinates; every drawing call takes local ones.** That asymmetry is deliberate and documented at the method, but it is the one thing in `internal/ui` that will surprise you. |
| 51 | - **The quality gate is not `make test`.** Both have to pass, and the quality report is a separate command. |