Align the TUI help legend into a fixed-width column grid.
CI / test-and-build (push) Failing after 1m31s
CI / demo (push) Skipped

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-28 00:17:44 +01:00
co-authored by Cursor
parent 229f7a2fe1
commit 98fcb57298
+49 -31
View File
@@ -152,42 +152,60 @@ func (m Model) helpSep() string {
return sep return sep
} }
// wrapHelpParts packs styled help snippets into lines that fit within width. // padHelpCell pads a styled help snippet to cellW visible columns.
func wrapHelpParts(parts []string, width int, sep string) []string { func padHelpCell(part string, cellW int) string {
pad := cellW - lipgloss.Width(part)
if pad < 0 {
pad = 0
}
return part + strings.Repeat(" ", pad)
}
// tableHelpParts lays out styled help snippets as a fixed-width column grid.
func tableHelpParts(parts []string, width int, sep string) []string {
if len(parts) == 0 {
return []string{""}
}
if width < 1 { if width < 1 {
width = 1 width = 1
} }
sepW := lipgloss.Width(sep)
var lines []string
var cur string
cellW := 0
for _, p := range parts { for _, p := range parts {
pw := lipgloss.Width(p) if w := lipgloss.Width(p); w > cellW {
if cur == "" { cellW = w
cur = p }
// Oversized single entry still gets its own line so nothing is dropped. }
if pw > width { if cellW < 1 {
lines = append(lines, cur) cellW = 1
cur = "" }
sepW := lipgloss.Width(sep)
cols := 1
if cellW <= width {
cols = (width + sepW) / (cellW + sepW)
if cols < 1 {
cols = 1
}
}
var lines []string
for i := 0; i < len(parts); i += cols {
end := i + cols
if end > len(parts) {
end = len(parts)
}
row := parts[i:end]
cells := make([]string, len(row))
for j, p := range row {
// Pad every cell except a lone oversized entry on its own row.
if len(row) == 1 && lipgloss.Width(p) > width {
cells[j] = p
} else {
cells[j] = padHelpCell(p, cellW)
} }
continue
} }
if lipgloss.Width(cur)+sepW+pw <= width { lines = append(lines, strings.Join(cells, sep))
cur = cur + sep + p
continue
}
lines = append(lines, cur)
cur = p
if pw > width {
lines = append(lines, cur)
cur = ""
}
}
if cur != "" {
lines = append(lines, cur)
}
if len(lines) == 0 {
return []string{""}
} }
return lines return lines
} }
@@ -203,8 +221,8 @@ func (m Model) renderFooter() string {
sep := m.helpSep() sep := m.helpSep()
parts := m.helpParts() parts := m.helpParts()
// Wrap help across the full width so all bindings stay visible. // Table layout so key/desc columns stay aligned across rows.
lines := wrapHelpParts(parts, width, sep) lines := tableHelpParts(parts, width, sep)
// Place version on the last line to the right when it fits; otherwise // Place version on the last line to the right when it fits; otherwise
// put it on an extra right-aligned line. // put it on an extra right-aligned line.