# Handoff — 2026-08-30 — two defects found by running it for real ## State The user ran the editor in an actual terminal for the first time and found two defects. Both are **fixed, tested and shipped**; the quality gate is back to PASS and the whole suite is green under `-race`. 1. **The cursor was invisible under `turbo-dark`.** The editor relied entirely on the terminal to draw the cursor, and a terminal draws it in the *user's* colour, which owes nothing to the theme. The editor now paints the cursor cell itself, in a new `editor.cursor` theme key, and only the active window does so. 2. **Completion returned nothing.** `main` opens the files named on the command line and *then* starts gopls, so the first `didOpen` reached nothing at all. gopls was never told the document was open, so the `didChange` sent on every keystroke referred to a document it did not have — and it answered completions from the **stale on-disk text**. Typing `fmt.` gave "No completions here". The editor now re-announces every open document once the server becomes ready. Along the way: the completion popup was anchored without allowing for the gutter or the horizontal scroll, so it opened several columns left of the cursor. Also fixed. ## The lesson, which matters more than the fixes Both defects were invisible to a test suite that never leaves memory. - `tcell.SimulationScreen` exercises the drawing code faithfully, but it is not a TTY. It cannot tell you that a real terminal will draw a cursor you cannot see. - The first version of the end-to-end completion test **passed with the fix removed**, because its fixture already contained `strings.` on disk and gopls answered from disk. A test whose fixture contains the answer proves nothing about what the editor said. It was rewritten to *type* the text, and only then did it fail without the fix. If you add a test involving a language server, make sure the thing being completed exists **only in the buffer**. ## Next steps 1. **Another real-terminal pass**, now that two of these have been found there. Still unverified on hardware: mouse reporting (drag, resize, click-to-place), `Alt`-key handling, resize mid-session, and how `borland-light` looks. 2. **Show diagnostics where the error is.** Unchanged from the previous handoff: `Language.Diagnostics(path)` holds them per file, the status bar shows only the first, and the `diagnostic.*` theme keys are drawn by nothing. 3. **CI**, so `make test` plus the quality report stop being a manual ritual. 4. macOS and Windows have still never run this. ## Open questions / blockers - **Is the amber cursor right for `turbo-dark`?** `#ffd787` on `#262626` is loud on purpose, because the complaint was that it could not be seen. If it is now too loud, the key to change is `editor.cursor` and the how-to explains it. - Unchanged from the previous handoff: the empty `.tickets/0001-specifications.yaml`, no licence headers, and `kits/` being untracked yet excluded from qlty. ## Watch out for Everything in the previous handoff still applies. Two more: - **`Window.SetActive` now propagates the focus to its content.** A content widget that implements `ui.Focusable` will be focused and unfocused by the window. `editor.View` embeds `ui.FocusBox` for this reason, and a view built on its own starts focused so that it still shows a cursor outside a desktop. - **`editor.cursor` must not be a reversal of `editor.currentline`.** Some terminals draw their cursor by inverting the cell; a reversed pair would be inverted straight back into invisibility. A test in `internal/editor` checks every theme for exactly that.