@@ -205,6 +205,36 @@ filtering in the drawer; an unread count in the bar (cut here because its
205205reset semantics are undefined, and "do something simple for now"); an
206206alternative sink; nvim-style levels with timeouts.
207207
208+ ## 4a. One picker, three drawers
209+
210+ The completion menu already is the thing the queue and notifications want to be:
211+ a fixed-height window over a longer list, one selected row, `^N`/`^P` to move,
212+ `Esc` to dismiss, and an honest marker for what is out of view. It is written
213+ once, inside the command box, and the queue drawer has a second, poorer copy of
214+ half of it.
215+
216+ **Extract it.** A `picker` owns rows, a cursor, and a page:
217+
218+ ```go
219+ type picker struct {
220+ rows []drawerRow
221+ cursor int // -1: nothing selected
222+ top int // first visible row; the window slides to keep cursor in view
223+ }
224+
225+ func (p *picker ) move (d int ) // ^N / ^P, and repeated Tab
226+ func (p *picker) window(h int) []string // the visible slice + the "… N more" marker
227+ ```
228+
229+ Three consumers, one behaviour: **completions** (columns, inserts on move),
230+ **queue** (rows, `x` drops), **notifications** (rows, `y` yanks). What differs
231+ is the row renderer and the verb keys, which stay with each drawer; what is
232+ shared is everything a reader's fingers touch.
233+
234+ **The truncation marker is `cmdkit.AndMore`** (build step 4), so "… 749 more"
235+ reads identically in a picker, in `form show` and in `figaro ls`. A list that
236+ lies about its own length is the one failure mode all three share.
237+
208238## 5. Verbose (`^V`), and the paste it must not eat
209239
210240`^O` (verbose tool output) is a different axis and stays. `^V` toggles **the
@@ -253,8 +283,11 @@ Each step ships alone; none changes what the pager can do.
2532833. **`statusView` + goldens** (§1) — the bar renders from a value.
2542844. **`cmdkit.AndMore(n, hint)`** — one spelling of "… 749 more" for the drawer,
255285 `form show` and the `ls` family, which have three today.
256- 5. **notifications** (§4) — the only new surface.
257- 6. **`^V`** (§5) — last: the only binding change.
286+ 5. **the `picker`** (§4a) — extracted from the completion menu, adopted by the
287+ queue. It lands before notifications so that notifications is only a row
288+ renderer and a sink, not a fourth copy of a list.
289+ 6. **notifications** (§4) — the only new surface.
290+ 7. **`^V`** (§5) — last: the only binding change.
258291
259292## Decided for you — each reversible with one line
260293
0 commit comments