Two boundary cases in cmd/openapi/internal/explore/tui/model.go, found while adding key-handler tests for #254. Both are on main today and unrelated to the bubbletea v2 change.
-
ensureCursorVisible cannot fit the cursor on a one-row content area. With height: 8, calculateContentHeight() returns 1. Once the cursor is past row 0, any non-zero scrollOffset costs one line for the "more items above" indicator plus one for the cursor row, which never fits in 1, so the search loop finds no offset and leaves scrollOffset = 0 with the cursor off-screen. Measured: height=8, cursor=5 -> scrollOffset=0, visible rows 0..0. The test TestUpdate_HalfPageKeys/ctrl+u still moves one row on a tiny terminal documents this by skipping the viewport assertion.
-
ctrl+d on an empty operation list sets cursor = -1: maxItems = len(m.operations) - 1 is -1 and the clamp assigns it. Unreachable through the CLI, since explore and snip both refuse an empty list before starting the TUI, so this is hygiene rather than a user-visible bug.
Suggested fixes: for (1), either let the cursor row win over the indicator when only one row fits, or have calculateContentHeight reserve the indicator line so the loop's budget is honest; for (2), the same len(m.operations) > 0 guard G already has. Happy to send a PR for both once #254 lands, so the tests can assert the tight bound everywhere.
Two boundary cases in
cmd/openapi/internal/explore/tui/model.go, found while adding key-handler tests for #254. Both are onmaintoday and unrelated to the bubbletea v2 change.ensureCursorVisiblecannot fit the cursor on a one-row content area. Withheight: 8,calculateContentHeight()returns 1. Once the cursor is past row 0, any non-zeroscrollOffsetcosts one line for the "more items above" indicator plus one for the cursor row, which never fits in 1, so the search loop finds no offset and leavesscrollOffset = 0with the cursor off-screen. Measured:height=8, cursor=5 -> scrollOffset=0, visible rows 0..0. The testTestUpdate_HalfPageKeys/ctrl+u still moves one row on a tiny terminaldocuments this by skipping the viewport assertion.ctrl+don an empty operation list setscursor = -1:maxItems = len(m.operations) - 1is -1 and the clamp assigns it. Unreachable through the CLI, sinceexploreandsnipboth refuse an empty list before starting the TUI, so this is hygiene rather than a user-visible bug.Suggested fixes: for (1), either let the cursor row win over the indicator when only one row fits, or have
calculateContentHeightreserve the indicator line so the loop's budget is honest; for (2), the samelen(m.operations) > 0guardGalready has. Happy to send a PR for both once #254 lands, so the tests can assert the tight bound everywhere.