diff --git a/internal/commands/commands.go b/internal/commands/commands.go index c775a70..ba90130 100644 --- a/internal/commands/commands.go +++ b/internal/commands/commands.go @@ -2,7 +2,6 @@ package commands import ( "fmt" - "strings" "github.com/apache/arrow-go/v18/parquet/file" "github.com/noppaz/collie/internal/parse" @@ -74,9 +73,7 @@ func LessCommand(filename string, amount int) error { return err } - tableString := visualize.LipglossTable(headers, rows).String() - header := strings.Join(strings.Split(tableString, "\n")[:3], "\n") - content := strings.Join(strings.Split(tableString, "\n")[3:], "\n") + header, content := visualize.LipglossTableWithSections(headers, rows) return visualize.ViewportCreator(header, content) } diff --git a/internal/visualize/table.go b/internal/visualize/table.go index c4e9328..1b0dd55 100644 --- a/internal/visualize/table.go +++ b/internal/visualize/table.go @@ -2,6 +2,7 @@ package visualize import ( "os" + "strings" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" @@ -12,6 +13,26 @@ const ( ) func LipglossTable(headers []string, rows [][]string) *table.Table { + columnWidths := lipglossTableColumnWidths(headers, rows) + return newLipglossTable(headers, rows, columnWidths) +} + +func LipglossTableWithSections(headers []string, rows [][]string) (header string, body string) { + columnWidths := lipglossTableColumnWidths(headers, rows) + fullTable := newLipglossTable(headers, rows, columnWidths).String() + if len(rows) == 0 { + return fullTable, "" + } + + headerTable := newLipglossTable(headers, nil, columnWidths). + BorderBottom(false) + + header = headerTable.String() + body = strings.TrimPrefix(fullTable, header+"\n") + return header, body +} + +func lipglossTableColumnWidths(headers []string, rows [][]string) map[int]int { columnWidths := make(map[int]int, 0) for i, header := range headers { rowLength := 0 @@ -21,6 +42,10 @@ func LipglossTable(headers []string, rows [][]string) *table.Table { columnWidths[i] = max(len(header), rowLength) + 2 } + return columnWidths +} + +func newLipglossTable(headers []string, rows [][]string, columnWidths map[int]int) *table.Table { re := lipgloss.NewRenderer(os.Stdout) headerStyle := re.NewStyle().Foreground(orange).Bold(true).Align(lipgloss.Center) rowStyle := re.NewStyle().Padding(0, 1) diff --git a/internal/visualize/table_test.go b/internal/visualize/table_test.go index e378f25..cbf90ab 100644 --- a/internal/visualize/table_test.go +++ b/internal/visualize/table_test.go @@ -26,3 +26,33 @@ func Test_LipglossTable(t *testing.T) { ) } } + +func Test_LipglossTableSections(t *testing.T) { + headers := []string{"col 1", "col 2", "col 3 with long name"} + rows := [][]string{{"row 1", "long value row 1", "1"}, {"row 2", "long value row 2", "2"}} + + header, body := LipglossTableWithSections(headers, rows) + + expectedHeader := `┌───────┬──────────────────┬──────────────────────┐ +│ col 1 │ col 2 │ col 3 with long name │ +├───────┼──────────────────┼──────────────────────┤` + expectedBody := `│ row 1 │ long value row 1 │ 1 │ +│ row 2 │ long value row 2 │ 2 │ +└───────┴──────────────────┴──────────────────────┘` + + if header != expectedHeader { + t.Errorf( + "LipglossTableSections header mismatch\nGot:\n%s\nExpected:\n%s\n", + header, + expectedHeader, + ) + } + + if body != expectedBody { + t.Errorf( + "LipglossTableSections body mismatch\nGot:\n%s\nExpected:\n%s\n", + body, + expectedBody, + ) + } +}