Skip to content

fix(ui): fit bordered panels and the status bar inside the terminal - #115

Merged
kwrkb merged 1 commit into
mainfrom
fix/ui-panel-border-statusbar-wrap
Sep 19, 2026
Merged

kwrkb merged 1 commit into
mainfrom
fix/ui-panel-border-statusbar-wrap

Conversation

@kwrkb

@kwrkb kwrkb commented Sep 18, 2026

Copy link
Copy Markdown
Owner

What changed

  • internal/ui/result.go: new framedPanel helper. It renders a bordered result panel that takes exactly w×h cells, border included. It gets the border size from the style (GetHorizontalBorderSize / GetVerticalBorderSize). Both result-panel paths use it.
  • internal/ui/compare.go: both compare panes use framedPanel.
  • internal/ui/sidebar.go: the sidebar's content is one cell narrower, so the sidebar plus its right border takes exactly sidebarWidth.
  • internal/ui/statusbar.go: the status bar always stays one row.
    • When there isn't room, the hints are cut first, with ….
    • The whole bar is then truncated to the terminal width, for the case where a long DSN or message still doesn't fit.
  • internal/ui/model.go:
    • editorHeight / resultsHeight now split m.height-1, via the new bodyHeight. They used to split m.height-3.
    • The editor gets fullWidth. It used to get fullWidth-4.
  • internal/ui/layout_test.go: two new tests.
    • TestViewFitsTerminal: across 4 sizes × 4 modes (insert / normal / sidebar / compare), the view must be exactly the terminal height, every line exactly the terminal width, and the results' bottom-right corner must be visible.
    • TestStatusBarStaysOneRow: the status bar must be exactly 1 row and exactly the terminal width for every width from 1 to 200.
  • LESSONS.md / NOTES.md: one lesson entry, and one index line for framedPanel.

Why

In lipgloss v1, Width and Height do not include the border. A bordered block given the full size therefore rendered two cells wider and taller than the space it had, and the renderer cut off the extra. Measured in a 120×30 terminal (tmux capture-pane):

  • The result panel always lost its right and bottom border. Its top border was 120 cells, and there was no right edge.
  • In compare mode, the right pane ran past the screen edge (124 cells).
  • With the sidebar open, the main area was one cell past the right edge.
  • The status bar hints wrapped: 2 rows at 120 columns, 3 rows at 80 columns. This happened in INSERT mode too, when the DB path was long. The extra rows took space from the result pane, and the end of the bar was cut off.

Once the panels had the correct size, two more problems became visible:

  • The height math subtracted two rows "for JoinVertical newlines". JoinVertical doesn't add rows, so the bottom two rows of the screen were always empty.
  • The editor was given fullWidth-4, but textarea.SetWidth already counts its own border. So the editor ended 4 cells short of the result panel.

Notes for reviewers

  • The result panel shows 2 more rows than before. Table heights (resultsHeight-4) and visibleColumnRange (contentWidth-8) are unchanged. They were already conservative for the new, smaller inner size.
  • Out of scope: at very small sizes (about 30×10 and below), the editor's textarea still wraps its own border. That happened before this change too; it looked the same or worse.
  • Without the production changes, all 16 TestViewFitsTerminal cases and TestStatusBarStaysOneRow fail. With them, everything passes.
  • Checked: go vet ./..., go test ./..., and bash e2e/run.sh (8/8 passed).
  • Also checked by hand in tmux: the built binary at 120×30, 100×24, 80×24, and 50×20, in insert, normal, sidebar, and compare modes.

🤖 Generated with Claude Code

lipgloss v1 sizes Width/Height without the border, so every bordered
block handed the full size rendered two cells wider and taller than
asked and the renderer clipped it:

- the result panel always lost its right and bottom edges
- compare mode ran its second pane off the right of the screen
- the sidebar pushed the main area one cell past the right edge

framedPanel now subtracts the frame from the style itself, and the
sidebar gives its right border the last of sidebarWidth.

The status bar wrapped whenever its hints (or a long DSN) did not fit,
growing the view and losing its tail to the MaxHeight crop. Hints are
now cut first and the whole bar is truncated to one row as a guard.

With the panels sized correctly, two more leftovers became visible:
editorHeight/resultsHeight reserved two rows for JoinVertical newlines
that add no rows, leaving the bottom of the screen blank, and the
editor was given fullWidth-4 although textarea.SetWidth already counts
its own border. Both now use the full space.

TestViewFitsTerminal asserts every line is exactly the terminal width
and the view exactly its height across sizes and modes; all 16 cases
failed before this change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-18T15:54:46.343001Z c2e7b47 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@kwrkb
kwrkb merged commit 00e7ead into main Sep 19, 2026
3 checks passed
@kwrkb
kwrkb deleted the fix/ui-panel-border-statusbar-wrap branch September 19, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant