diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-05 21:50:58 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-05 21:50:58 +0200 |
| commit | a4298701546b09fccb15ce30db7c7e3f4070525c (patch) | |
| tree | b3433014284ccd354be48efb2ce125ccaf236d7e /internal/tui/common | |
| parent | 2bd89ced830f97fd12a672fddb6978d204a014fd (diff) | |
fix(tui): stabilize full-width layout and sparkline rendering
Diffstat (limited to 'internal/tui/common')
| -rw-r--r-- | internal/tui/common/viewport.go | 22 | ||||
| -rw-r--r-- | internal/tui/common/viewport_test.go | 41 |
2 files changed, 56 insertions, 7 deletions
diff --git a/internal/tui/common/viewport.go b/internal/tui/common/viewport.go index 099a4e1..d54c886 100644 --- a/internal/tui/common/viewport.go +++ b/internal/tui/common/viewport.go @@ -1,13 +1,35 @@ package common +import ( + "os" + + xterm "github.com/charmbracelet/x/term" +) + const ( defaultViewportWidth = 80 defaultViewportHeight = 24 ) +var queryTerminalSize = func() (int, int, error) { + return xterm.GetSize(os.Stdout.Fd()) +} + // EffectiveViewport returns a usable terminal viewport size. Missing or invalid // dimensions fall back to defaults. func EffectiveViewport(width, height int) (int, int) { + if width <= 0 || height <= 0 { + terminalWidth, terminalHeight, err := queryTerminalSize() + if err == nil { + if width <= 0 && terminalWidth > 0 { + width = terminalWidth + } + if height <= 0 && terminalHeight > 0 { + height = terminalHeight + } + } + } + if width <= 0 { width = defaultViewportWidth } diff --git a/internal/tui/common/viewport_test.go b/internal/tui/common/viewport_test.go index c90f046..2dda81b 100644 --- a/internal/tui/common/viewport_test.go +++ b/internal/tui/common/viewport_test.go @@ -3,6 +3,14 @@ package common import "testing" func TestEffectiveViewport(t *testing.T) { + originalQuery := queryTerminalSize + t.Cleanup(func() { + queryTerminalSize = originalQuery + }) + queryTerminalSize = func() (int, int, error) { + return 132, 41, nil + } + tests := []struct { name string width int @@ -18,24 +26,24 @@ func TestEffectiveViewport(t *testing.T) { wantHeight: 40, }, { - name: "both missing use defaults", + name: "both missing use terminal size", width: 0, height: 0, - wantWidth: defaultViewportWidth, - wantHeight: defaultViewportHeight, + wantWidth: 132, + wantHeight: 41, }, { - name: "missing height uses default", + name: "missing height uses terminal size", width: 100, height: 0, wantWidth: 100, - wantHeight: defaultViewportHeight, + wantHeight: 41, }, { - name: "missing width uses default", + name: "missing width uses terminal size", width: -1, height: 30, - wantWidth: defaultViewportWidth, + wantWidth: 132, wantHeight: 30, }, } @@ -47,3 +55,22 @@ func TestEffectiveViewport(t *testing.T) { } } } + +func TestEffectiveViewportFallsBackToDefaultsWhenTerminalQueryFails(t *testing.T) { + originalQuery := queryTerminalSize + t.Cleanup(func() { + queryTerminalSize = originalQuery + }) + queryTerminalSize = func() (int, int, error) { + return 0, 0, assertiveError{} + } + + gotWidth, gotHeight := EffectiveViewport(0, 0) + if gotWidth != defaultViewportWidth || gotHeight != defaultViewportHeight { + t.Fatalf("got (%d,%d), want (%d,%d)", gotWidth, gotHeight, defaultViewportWidth, defaultViewportHeight) + } +} + +type assertiveError struct{} + +func (assertiveError) Error() string { return "terminal query failed" } |
