Handoff — 2026-08-31 — snippets, and submenus in the menu bar
State
Ticket 0006 is done and green, on branch feature/snippets, uncommitted.
Alt-N opens a Snippets menu built from .turbo-go/snippets.toml and the user's own file, grouped into submenus and filtered by the language of the front window. Choosing one inserts it at the cursor, re-indented to the line it landed on, as one undo step. Snippets ▸ Create snippets file writes a commented starter file and opens it.
File Edit Search Run Options Window Snippets Help
┌───────────────┐┌──────────────────────┐
│ if err != nil ││ Go ▶ │
│ table test ││ General ▶ │
└───────────────┘├──────────────────────┤
│ Create snippets file │
└──────────────────────┘
uigained one level of submenus (MenuItem.Items) andMenu.OnOpen.menu.gowas split four ways:menu.go(types and state),menu_draw.go,menu_events.go,submenu.go.- New
internal/snippets(83.8 %),editor.InsertSnippet(editor 96.2 %),internal/app/snippets.go. - Whole suite green under
-race. Quality gate PASS: 0/0/0, complexity 1480. - Docs complete in EN and FR — three new pages each, five existing pages updated each.
docs/diagrams/packages.drawiogainedsnippetsand three edges, re-checked againstgo list(34 edges each side). - Verified in a real terminal through the project's own VT emulator: the menu, the submenu (which flipped left for want of room), the file creation, and a four-line snippet inserted with correct indentation.
Earlier the same day, PR #5 merged the Markdown/JavaScript/HTML/shell colouring.
In flight
Nothing. Finished through Phase 8.
Next steps
- Commit and open the PR.
feature/snippetsis the branch. - Try it with thirty snippets. The submenu geometry was verified with two groups of two. A group with twenty items is taller than the terminal, and nothing scrolls a menu panel — see the blockers below.
- Tickets. 0002, 0003, 0006, 0007, 0009, 0013 and 0014 are all implemented and all still
state: open.
Open questions / blockers
- A menu panel does not scroll.
dropdownBoundsandsubmenuBoundsarelen(items)+2tall with no cap, so a group of thirty snippets draws a panel taller than the terminal and the bottom is simply clipped by the painter. This existed before — the Window menu has never been long enough to hit it — and snippets are the first thing that can. It wants either a scrolling panel or a "…" overflow item, and it is auifeature to decide on rather than something to slip in. - Placeholders and tab stops are absent (
${1:name}, moving between them). Deliberate: a second feature with state to maintain across edits. Thebodyis inserted verbatim apart from indentation. - Nothing rebuilds the menu bar itself.
OnOpenrefills a menu's items, but the set of menus is fixed at start-up. That is fine today; a feature wanting to add or remove a whole menu at runtime would need more.
Watch out for
- Two menus sharing a hot key silently make one unreachable.
handleClosedKeyreturns on the first match, so~S~nippetsbeside~S~earchmeantAlt-Snever reached Snippets — and every test passed. It was found by driving the real binary.TestNoTwoMenusShareAHotKeycovers it now; keep it, and check it when adding a menu. - Flipping a submenu left does not fit a panel wider than the terminal. The width is capped to the screen as well, and long labels are clipped by the painter.
TestASubmenuFlipsLeftWhenThereIsNoRoomOnTheRightfailed exactly on this before the cap. MenuItem.enabled()must treat a submenu as choosable. It used to return false for an item with noAction, which made every branch disabled and every submenu unreachable.TestAnItemWithNoActionButASubmenuCanStillBeChosenpins it.SetTextmarks a buffer modified, soModified()cannot show that an editor operation did nothing. UseRevision()—TestInsertingAnEmptySnippetChangesNothingwas wrong until it did.- The snippets tests must set
TURBO_GO_SNIPPET_DIR. Without it they read the snippets of whoever is running them, and pass or fail by accident. Every test ininternal/snippetsandinternal/appthat touches snippets sets it to an empty temp directory. - The template's bodies contain the two characters
\andt, not a tab. TOML interprets the escape on read.TestTheCreatedFilesTabsSurviveTOMLchecks the tab comes back out; a "helpful" replacement with a real tab would leave the template at the mercy of whatever a reader's editor does with tabs.
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 41 42 43 44 45 46 47 48 49 50 |
|