-
Notifications
You must be signed in to change notification settings - Fork 60
View() renders 6 columns wider than the terminal width, wrapping the status row #181
Description
Summary
App.View() returns a frame 6 columns wider than the width it was given. In a real terminal this overflows: the status row wraps onto an extra line, which pushes the frame down and scrolls the top row off screen.
Evidence
Measured with ansi.StringWidth (OSC-safe) against the golden snapshots added in the Phase 0 test work. Every line of every frame is a single uniform width — the overflow is not ragged:
| scenario | declared | rendered width | lines |
|---|---|---|---|
| base | 120x36 | 126 | 36 |
| drag_selection | 120x36 | 126 | 36 |
| no_sidebar | 120x36 | 126 | 36 |
| thread_open | 140x30 | 146 | 30 |
| wide | 200x50 | 206 | 50 |
| narrow | 80x24 | 86 | 24 |
| window_split | 160x40 | 166 | 40 |
| overlay_finder | 120x36 | 120 | 36 |
overlay_finder is the only one that is correct, and only by accident: maybeWrapFinalScreen clamps the frame, but it is gated on a.overlayActive() (internal/ui/view_overlays.go:108-111). With no overlay open, nothing clamps.
Root cause
internal/ui/statusbar/model.go builds the status row as left + filler + rightContent + rightPad, having budgeted the content at width - 1. But the spacer segments are each rendered through styles.StatusBar, which carries Padding(0, 1):
// internal/ui/styles/styles.go:467 StatusBar = lipgloss.NewStyle(). Background(SurfaceDark).Foreground(TextPrimary).Padding(0, 1)
Every styles.StatusBar.Render(...) therefore adds 2 columns that the width budget never accounted for. In model.go:340-357 that happens three times on the help-hint branch (leftPad, rightPad), once on the no-hint branch, and once more for the trailing rightPad gutter — which renders a single space as 3 columns.
There appear to be two overflow magnitudes depending on which branch runs: +6 when the help hint is shown (all measurements above) and +4 on the branch where the hint is dropped for lack of room. A sufficiently narrow terminal would hit the second.
Impact
Real. Any terminal whose width equals the reported width will wrap the status row. The visible symptom is the top line of the message pane scrolling away, which reads as a rendering glitch rather than an overflow.
Reproduction
Run slk in a terminal and compare the status row's right edge against the terminal edge, or run the golden measurement above on refactor/phase0-safety-net.
Note for whoever fixes this
internal/ui/golden_test.go currently encodes the bug as a constant so the golden width guard can assert against reality:
const goldenStatusOverflow = 6
When this bug is fixed, set that constant to 0 and re-bless the eight goldens (go test ./internal/ui -run TestGolden -update). The constant carries a comment pointing here. The overlayActive() exception in the guard can be removed at the same time, since all frames will then be exactly w.
Provenance
Found while building golden-image tests for the architecture refactor (Phase 0). Not fixed there, because that phase is behaviour-preserving by construction and permits exactly one production change. Confirmed independently by two reviewers.