Skip to content

Commit 1632f84

Browse files
committed
fix(tui): use lipgloss.Width in padRight/padLeft and split embedded newlines in addLog
- padRight/padLeft used len(s) which counts ANSI escape bytes as visible chars. Styled strings (accentStyle, warnStyle...) had len >> visual width, causing the status/version/source columns to overflow into description → columns gone. Fixed by using lipgloss.Width() for measurement and truncate() for cutting. - addLog stored Nuxt multi-line chunks as a single logLines entry. The panel height calculation counted 1 line but the renderer produced N lines via the embedded \n → panel exceeded allocated height → wave/surf scroll effect. Fixed by splitting on \n before storing, skipping empty sub-lines.
1 parent 788a3cd commit 1632f84

2 files changed

Lines changed: 21 additions & 8 deletions

File tree

go/tui/helpers.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -437,17 +437,19 @@ func truncate(s string, max int) string {
437437
}
438438

439439
func padRight(s string, width int) string {
440-
if len(s) >= width {
441-
return s[:width]
440+
vis := lipgloss.Width(s)
441+
if vis >= width {
442+
return truncate(s, width)
442443
}
443-
return s + strings.Repeat(" ", width-len(s))
444+
return s + strings.Repeat(" ", width-vis)
444445
}
445446

446447
func padLeft(s string, width int) string {
447-
if len(s) >= width {
448-
return s[:width]
448+
vis := lipgloss.Width(s)
449+
if vis >= width {
450+
return truncate(s, width)
449451
}
450-
return strings.Repeat(" ", width-len(s)) + s
452+
return strings.Repeat(" ", width-vis) + s
451453
}
452454

453455
func formatCatalogAge(iso *string) string {

go/tui/tui.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,12 +471,23 @@ func (m *TuiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
471471
}
472472

473473
func (m *TuiModel) addLog(line string) {
474-
m.logLines = append(m.logLines, line)
474+
// Split on embedded newlines — Nuxt can emit multi-line chunks as a single string.
475+
// If we store them unsplit, the panel renders 1 counted line but N terminal lines → layout breaks.
476+
line = strings.ReplaceAll(line, "\r\n", "\n")
477+
sublines := strings.Split(line, "\n")
478+
for _, sl := range sublines {
479+
sl = strings.TrimRight(sl, "\r")
480+
if sl == "" {
481+
continue
482+
}
483+
m.logLines = append(m.logLines, sl)
484+
}
475485
if len(m.logLines) > 200 {
476-
m.logLines = m.logLines[1:]
486+
m.logLines = m.logLines[len(m.logLines)-200:]
477487
}
478488
}
479489

490+
480491
func (m *TuiModel) checkForUpdatesCmd() tea.Cmd {
481492
return func() tea.Msg {
482493
gitChangesMap := make(map[string]GitChanges)

0 commit comments

Comments
 (0)