Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions internal/picker/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ func (m Model) View() tea.View {

list := m.listView(t, groups, rows, lay, now)
if lay.ShowPreview {
// The preview column is joined under a matching blank line so its
// box's top border lands on the list's first row, not on the
// filter line above.
right := "\n" + m.previewView(t, rows, lay, now)
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, list, " ", right))
// The preview box is exactly ListHeight lines tall (lipgloss v2
// counts the border in Height), so joining it at the top keeps
// the frame at the terminal height: one taller and the renderer
// drops the filter line and repaints every tick.
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, list, " ", m.previewView(t, rows, lay, now)))
} else {
b.WriteString(list)
}
Expand Down Expand Up @@ -204,7 +204,8 @@ func (m Model) previewView(t theme, rows []match, lay Layout, now time.Time) str
BorderForeground(t.rule).
Padding(0, 1).
Width(lay.PreviewWidth).
Height(lay.ListHeight)
Height(lay.ListHeight).
MaxHeight(lay.ListHeight) // Height is a minimum; a tall body must not grow the box
return box.Render(body.String())
}

Expand Down
22 changes: 22 additions & 0 deletions internal/picker/view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,25 @@ func TestModel_View_RowsShareEqualWidth(t *testing.T) {
}
}
}

// TestModel_View_FrameMatchesTerminalHeight pins the frame to exactly the
// terminal height, with and without the preview pane. One line taller and
// Bubble Tea's inline renderer drops the filter line off the top.
func TestModel_View_FrameMatchesTerminalHeight(t *testing.T) {
rows := manyRows(11)
for _, width := range []int{110, 45} {
for _, height := range []int{40, 30, 24, 14, 9} {
m := picker.NewModel(rows, noopStatus, picker.Options{})
next, _ := m.Update(tea.WindowSizeMsg{Width: width, Height: height})
m = next.(picker.Model)

lines := strings.Split(m.View().Content, "\n")
if len(lines) != height {
t.Errorf("View() at %dx%d produced %d lines, want exactly %d", width, height, len(lines), height)
}
if !strings.Contains(lines[0], "type to filter") {
t.Errorf("View() at %dx%d: first line %q is not the filter line", width, height, lines[0])
}
}
}
}