From 688d50fda37907d56801ee0e53065820fa486e14 Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Thu, 1 Sep 2022 15:55:38 +0200 Subject: [PATCH] fix(viewport): properly truncate to size There are many "interesting" cases: - logical content is wider than display width (long lines). In this case, we truncate. - logical content is smaller than display height (fewer lines than visible). In this case, we pad with empty lines up to the specified height. - logical content is higher than display height (more lines than visible). In this case, we truncate. - style specifies a width wider than the display width. In this case, we ignore the style width and fit in the display width. - style specifies a height higher than the display height. Same as width, we ignore the style and fit in the display height. - style specifies a narrower width or smaller height than the display. In this case we obey the style. --- viewport/viewport.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/viewport/viewport.go b/viewport/viewport.go index a2f708e9..c4c3b5ba 100644 --- a/viewport/viewport.go +++ b/viewport/viewport.go @@ -349,12 +349,24 @@ func (m Model) View() string { // position anything below this view properly. return strings.Repeat("\n", max(0, m.Height-1)) } - contentWidth := m.Width - m.Style.GetHorizontalFrameSize() - contentHeight := m.Height - m.Style.GetVerticalFrameSize() - return m.Style.Copy(). - UnsetWidth().MaxWidth(contentWidth). // truncate long lines. - Height(contentHeight).MaxHeight(contentHeight). // pad to height then truncate. + + w, h := m.Width, m.Height + if sw := m.Style.GetWidth(); sw != 0 { + w = min(w, sw) + } + if sh := m.Style.GetHeight(); sh != 0 { + h = min(h, sh) + } + contentWidth := w - m.Style.GetHorizontalFrameSize() + contentHeight := h - m.Style.GetVerticalFrameSize() + contents := lipgloss.NewStyle(). + Height(contentHeight). // pad to height. + MaxHeight(contentHeight). // truncate height if taller. + MaxWidth(contentWidth). // truncate width. Render(strings.Join(m.visibleLines(), "\n")) + return m.Style.Copy(). + UnsetWidth().UnsetHeight(). // Style size already applied in contents. + Render(contents) } func clamp(v, low, high int) int {