mirror of
https://github.com/chenasraf/cospend-cli.git
synced 2026-05-17 17:38:04 +00:00
98 lines
2.2 KiB
Go
98 lines
2.2 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/mattn/go-runewidth"
|
|
)
|
|
|
|
// Table border characters
|
|
const (
|
|
borderHorizontal = "─"
|
|
borderVertical = "│"
|
|
borderTopLeft = "┌"
|
|
borderTopRight = "┐"
|
|
borderBottomLeft = "└"
|
|
borderBottomRight = "┘"
|
|
borderTopMid = "┬"
|
|
borderBottomMid = "┴"
|
|
borderLeftMid = "├"
|
|
borderRightMid = "┤"
|
|
borderCross = "┼"
|
|
)
|
|
|
|
// Table handles formatted table output
|
|
type Table struct {
|
|
headers []string
|
|
rows [][]string
|
|
colWidths []int
|
|
}
|
|
|
|
// NewTable creates a new table with the given headers
|
|
func NewTable(headers ...string) *Table {
|
|
colWidths := make([]int, len(headers))
|
|
for i, h := range headers {
|
|
colWidths[i] = runewidth.StringWidth(h)
|
|
}
|
|
return &Table{
|
|
headers: headers,
|
|
colWidths: colWidths,
|
|
}
|
|
}
|
|
|
|
// AddRow adds a row to the table
|
|
func (t *Table) AddRow(values ...string) {
|
|
// Pad with empty strings if needed
|
|
for len(values) < len(t.headers) {
|
|
values = append(values, "")
|
|
}
|
|
// Truncate if too many
|
|
if len(values) > len(t.headers) {
|
|
values = values[:len(t.headers)]
|
|
}
|
|
|
|
t.rows = append(t.rows, values)
|
|
|
|
// Update column widths
|
|
for i, v := range values {
|
|
if w := runewidth.StringWidth(v); w > t.colWidths[i] {
|
|
t.colWidths[i] = w
|
|
}
|
|
}
|
|
}
|
|
|
|
// Render writes the table to the given writer
|
|
func (t *Table) Render(w io.Writer) {
|
|
t.printBorder(w, borderTopLeft, borderTopMid, borderTopRight)
|
|
t.printRow(w, t.headers)
|
|
t.printBorder(w, borderLeftMid, borderCross, borderRightMid)
|
|
|
|
for _, row := range t.rows {
|
|
t.printRow(w, row)
|
|
}
|
|
|
|
t.printBorder(w, borderBottomLeft, borderBottomMid, borderBottomRight)
|
|
}
|
|
|
|
func (t *Table) printBorder(w io.Writer, left, mid, right string) {
|
|
_, _ = fmt.Fprint(w, left)
|
|
for i, width := range t.colWidths {
|
|
_, _ = fmt.Fprint(w, strings.Repeat(borderHorizontal, width+2))
|
|
if i < len(t.colWidths)-1 {
|
|
_, _ = fmt.Fprint(w, mid)
|
|
}
|
|
}
|
|
_, _ = fmt.Fprintln(w, right)
|
|
}
|
|
|
|
func (t *Table) printRow(w io.Writer, values []string) {
|
|
_, _ = fmt.Fprint(w, borderVertical)
|
|
for i, val := range values {
|
|
padded := runewidth.FillRight(val, t.colWidths[i])
|
|
_, _ = fmt.Fprintf(w, " %s %s", padded, borderVertical)
|
|
}
|
|
_, _ = fmt.Fprintln(w)
|
|
}
|