# TUI `/` search filter Pressing `/` in the library or queue pane opens a search input that filters that pane's items live as you type (case-insensitive substring). A small feature; recorded here for the couple of decisions that were not obvious. ## Decisions ### D1 — filter, not jump Vim's `/` jumps to the next match; here `/` *narrows* the visible list to matching rows. For a music library ("show me everything with 'radiohead'") filtering is the more useful reading of "search in the items", and it composes with the existing queue/mark actions — you filter, then act on what is left. ### D2 — the filter lives on the pane, the input on the app The pane (`Library`/`Queue`) owns a `Filter` (the query plus the list of visible real indices). The `/` input mode (`App::search`) only holds the editing buffer and which pane is focused. So the filter *survives* closing the input: `Enter` keeps it applied and returns to navigation, `Esc` clears it. This matches the other modal overlays (input, confirm) in how keys are routed while it is open. ### D3 — view indices vs real indices The panes keep their full item list; the filter maps between the *view* index (what the selection bar and `StatefulList` navigation key off) and the *real* index into the list. This matters most for the queue: removal and set-current send **real queue positions** to the server, so a filtered selection must map back before it is sent — otherwise `d` on the third visible row would remove the wrong track. Marks likewise live on the full list, so a marked-but-hidden item still counts when queueing. Because `StatefulList` already routes through `get_size`/`select`/ `selected`, pointing those at the filtered view made all the movement keys (`j`/`k`/`g`/`G`/`Ctrl-d`/`Ctrl-u`) work on the filtered list with no per-key changes. ### D4 — lifecycle - **Library**: entering a node is a fresh listing, so search mode is reset there (a stale filter from the previous folder would be confusing). - **Queue**: the queue is re-sent constantly (position ticks, resolving), so an active search is *preserved* across updates and only its visible set is recomputed. ## Scope Implemented in the TUI only, per the request. The web client (`architecture/web-client.md`) could mirror it later for parity; noted as a follow-up, not done here.