feat: config option to use the List Layout (prototype variant C) for the Picker - #53
Merged
Merged
Conversation
The list layout marks its selected row with a background rather than a caret, so every segment of a row has to be rendered through a base style that carries it. statusCluster gains statusClusterOn, taking that base, and highlightMatches derives its match style from the base it is given instead of building a fresh one. The theme grows the selected row's background and foreground. Nothing renders differently yet: the derived match style is the same accent-bold-underline the old one was. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
LayoutStyle names the two layouts the Picker can draw, Options.Layout selects one (the zero value staying LayoutGrouped, the accepted look), and the Model remembers it. visibleRows states the row order the cursor indexes into for the active layout: grouped by Kind as before, or flat History order for the list layout. The View still draws the grouped layout either way. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prototype variant C, from the kept prototype/picker-look branch: a flat list with no Kind headers, "kind/" muted before each Project name, one status cluster per row, the relative time right-aligned, the filter prompt below the list where fzf users expect it, and a bar plus a background highlight on the selected row. View now dispatches on the Model's layout, with the frame size, the column budget, the preview pane and the footer shared between the two. Both layouts spend the same total width on their fixed columns, so ComputeLayout needs no change: the list layout just hands it "kind/name" as the name column's content. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
[picker] layout selects which layout the Picker draws: "grouped", the default and the look accepted in the prototype review, or "list". Any other value is a config error naming the two it accepts, matching how every other key is validated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resolve already forwards the vim key map; it now forwards picker.layout alongside it, so the config key reaches the Picker. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The name column gave the Kind all the room it asked for and truncated the Project name with whatever was left, so a Kind long enough to fill the column cut the name down to a rune or two and rendered it muted along with the Kind. The name is what the user is reading for: it now keeps a floor of its own and the Kind is the part that gives way, each segment still carrying its own style. listFrame also draws m.visibleRows() rather than m.visibleMatches(), the same order the cursor and choose() index, so the drawn order and the chosen Row cannot drift apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ding The two layouts had grown three copies of the same shapes: the frameSize/computeLayout pair, the block that clips a body to ListHeight and scrolls the cursor into it, and a plain and a base-styled pair of padding helpers. Sizing and clipping move to layout.go, where the rest of the per-frame geometry lives; the padding helpers collapse onto the base-styled pair in styles.go, with the grouped layout passing the zero style as statusCluster already does. view.go drops from 265 lines to 202. listView is renamed groupedBody: it draws the grouped body, and the name read as the list layout's once that layout existed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The frame height, the alternate screen and equal-width rows are shared behaviour, so they run as subtests over both layouts instead of the list layout keeping near-copies of each. The filter line's position is the one that differs, and it is now pinned from one table too: the top of the grouped frame, the line below the body in the list layout. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
quoteList existed for one call site with one fixed slice. The error now reads "picker.layout must be grouped or list". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Picker now draws one of two arrangements, and the concept had no agreed name: "layout", "variant" and "style" were all in play across the issue, the prototype and the code. Layout is the term, with the Grouped Layout and the List Layout as its two values, and the README uses them. Naming the values Grouped Layout and List Layout keeps the Picker's own _Avoid_ list intact: a bare "list" still must not mean the Picker. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Follow-up filed as #54: the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #44.
Adds a config key that selects the Picker's Layout, defaulting to the current one:
What
listdrawsThe List Layout renders prototype variant C from the kept
prototype/picker-lookbranch: a flat run of Projects in History order with never-visited ones last,kind/muted before each Project name, one status cluster per row, the relative time right-aligned, the filter prompt below the list where fzf users expect it, and a▌bar plus a background highlight on the selected row — with the same boxed preview pane on the right.Fuzzy matching, both key maps, the status glyphs, the colours and the narrow-terminal rules stay shared with the Grouped Layout.
ComputeLayoutneeded no change: both Layouts spend the same total width on their fixed columns, so the List Layout just hands itkind/nameas the name column's content.Unknown values are a config error (
picker.layout must be grouped or list, got "fancy"), matching how every other key is validated.Notes for the reviewer
8dda3c4).703cf5btouches the Grouped Layout's render path —statusClusterOn, and a match style derived from the row's base style — so the selected row's background runs through the glyphs and the matched runes. Output in the Grouped Layout is unchanged; its existing tests were not modified.CONTEXT.mdgains aLayoutentry. Naming the values Grouped Layout and List Layout keeps the Picker's own_Avoid_list intact: a bare "list" still must not mean the Picker.Known follow-up
The glossary entry sharpens a naming collision already in the code:
picker.Layoutis a struct holding per-frame sizing (NameWidth,ListHeight,ShowPreview), which is not the domain concept. By the glossary the arrangement should ownLayoutand the sizing struct is really frame geometry. Renaming it is an exported-API change across the package, so it is deliberately left out of this PR.Verification
go build,go vet,golangci-lint(0 issues),go test ./..., all files under the 300-line limit (view.gowent 265 → 202). Also driven end-to-end under a pty against a real config to confirm the frame the binary actually draws.🤖 Generated with Claude Code