refactor: centralize table output helpers

This commit is contained in:
Peter Steinberger 2026-04-21 05:03:33 +01:00
parent 6076deba26
commit cd98a9d46d
No known key found for this signature in database
8 changed files with 45 additions and 37 deletions

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"text/tabwriter"
"time"
"github.com/spf13/cobra"
@ -45,14 +44,15 @@ func newChatsListCmd(flags *rootFlags) *cobra.Command {
return out.WriteJSON(os.Stdout, chats)
}
w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
fullOutput := fullTableOutput(flags.fullOutput)
w := newTableWriter(os.Stdout)
fmt.Fprintln(w, "KIND\tNAME\tJID\tLAST")
for _, c := range chats {
name := c.Name
if name == "" {
name = c.JID
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", c.Kind, truncate(name, 28), c.JID, c.LastMessageTS.Local().Format("2006-01-02 15:04:05"))
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", c.Kind, tableCell(name, 28, fullOutput), c.JID, c.LastMessageTS.Local().Format("2006-01-02 15:04:05"))
}
_ = w.Flush()
return nil

View File

@ -5,7 +5,6 @@ import (
"fmt"
"os"
"strings"
"text/tabwriter"
"github.com/spf13/cobra"
"github.com/steipete/wacli/internal/out"
@ -49,13 +48,14 @@ func newContactsSearchCmd(flags *rootFlags) *cobra.Command {
return out.WriteJSON(os.Stdout, cs)
}
w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
fullOutput := fullTableOutput(flags.fullOutput)
w := newTableWriter(os.Stdout)
fmt.Fprintln(w, "ALIAS\tNAME\tPHONE\tJID")
for _, c := range cs {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
truncate(c.Alias, 18),
truncate(c.Name, 24),
truncate(c.Phone, 14),
tableCell(c.Alias, 18, fullOutput),
tableCell(c.Name, 24, fullOutput),
tableCell(c.Phone, 14, fullOutput),
c.JID,
)
}

View File

@ -7,7 +7,6 @@ import (
"path/filepath"
"strconv"
"strings"
"text/tabwriter"
"github.com/spf13/cobra"
"github.com/steipete/wacli/internal/config"
@ -111,7 +110,7 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
return out.WriteJSON(os.Stdout, rep)
}
w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
w := newTableWriter(os.Stdout)
fmt.Fprintf(w, "STORE\t%s\n", rep.StoreDir)
fmt.Fprintf(w, "LOCKED\t%v\n", rep.LockHeld)
if rep.LockHeld && rep.LockInfo != "" {

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"text/tabwriter"
"time"
"github.com/spf13/cobra"
@ -78,14 +77,15 @@ func newGroupsListCmd(flags *rootFlags) *cobra.Command {
return out.WriteJSON(os.Stdout, gs)
}
w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
fullOutput := fullTableOutput(flags.fullOutput)
w := newTableWriter(os.Stdout)
fmt.Fprintln(w, "NAME\tJID\tCREATED")
for _, g := range gs {
name := g.Name
if name == "" {
name = g.JID
}
fmt.Fprintf(w, "%s\t%s\t%s\n", truncate(name, 40), g.JID, g.CreatedAt.Local().Format("2006-01-02"))
fmt.Fprintf(w, "%s\t%s\t%s\n", tableCell(name, 40, fullOutput), g.JID, g.CreatedAt.Local().Format("2006-01-02"))
}
_ = w.Flush()
return nil

View File

@ -50,10 +50,3 @@ func fullTableOutput(forceFull bool) bool {
func fullTableOutputWithTTY(forceFull, tty bool) bool {
return forceFull || !tty
}
func truncateForDisplay(s string, max int, full bool) string {
if full {
return sanitize(s)
}
return truncate(s, max)
}

View File

@ -4,14 +4,13 @@ import (
"fmt"
"io"
"strings"
"text/tabwriter"
"time"
"github.com/steipete/wacli/internal/store"
)
func writeMessagesList(dst io.Writer, msgs []store.Message, fullOutput bool) error {
w := tabwriter.NewWriter(dst, 2, 4, 2, ' ', 0)
w := newTableWriter(dst)
fmt.Fprintln(w, "TIME\tCHAT\tFROM\tID\tTEXT")
for _, m := range msgs {
chatLabel := m.ChatName
@ -20,17 +19,17 @@ func writeMessagesList(dst io.Writer, msgs []store.Message, fullOutput bool) err
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
m.Timestamp.Local().Format("2006-01-02 15:04:05"),
truncate(chatLabel, 24),
truncate(messageFrom(m), 18),
truncateForDisplay(m.MsgID, 14, fullOutput),
truncate(messageText(m), 80),
tableCell(chatLabel, 24, fullOutput),
tableCell(messageFrom(m), 18, fullOutput),
tableCell(m.MsgID, 14, fullOutput),
tableCell(messageText(m), 80, fullOutput),
)
}
return w.Flush()
}
func writeMessagesSearch(dst io.Writer, msgs []store.Message, fullOutput bool) error {
w := tabwriter.NewWriter(dst, 2, 4, 2, ' ', 0)
w := newTableWriter(dst)
fmt.Fprintf(w, "TIME\tCHAT\tFROM\tID\tMATCH\n")
for _, m := range msgs {
chatLabel := m.ChatName
@ -43,10 +42,10 @@ func writeMessagesSearch(dst io.Writer, msgs []store.Message, fullOutput bool) e
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
m.Timestamp.Local().Format("2006-01-02 15:04:05"),
truncate(chatLabel, 24),
truncate(messageFrom(m), 18),
truncateForDisplay(m.MsgID, 14, fullOutput),
truncate(match, 90),
tableCell(chatLabel, 24, fullOutput),
tableCell(messageFrom(m), 18, fullOutput),
tableCell(m.MsgID, 14, fullOutput),
tableCell(match, 90, fullOutput),
)
}
return w.Flush()
@ -68,7 +67,7 @@ func writeMessageShow(dst io.Writer, m store.Message) error {
}
func writeMessageContext(dst io.Writer, msgs []store.Message, selectedID string, fullOutput bool) error {
w := tabwriter.NewWriter(dst, 2, 4, 2, ' ', 0)
w := newTableWriter(dst)
fmt.Fprintln(w, "TIME\tFROM\tID\tTEXT")
for _, m := range msgs {
line := messageContextLine(m)
@ -77,9 +76,9 @@ func writeMessageContext(dst io.Writer, msgs []store.Message, selectedID string,
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
m.Timestamp.Local().Format("2006-01-02 15:04:05"),
truncate(messageFrom(m), 18),
truncateForDisplay(m.MsgID, 14, fullOutput),
truncate(line, 100),
tableCell(messageFrom(m), 18, fullOutput),
tableCell(m.MsgID, 14, fullOutput),
tableCell(line, 100, fullOutput),
)
}
return w.Flush()

View File

@ -31,13 +31,13 @@ func TestTruncate(t *testing.T) {
func TestTruncateForDisplay(t *testing.T) {
const longID = "3EB0B0E8A1B2C3D4E5F6A7B8C9D0"
if got := truncateForDisplay(longID, 14, true); got != longID {
if got := tableCell(longID, 14, true); got != longID {
t.Fatalf("force full = %q, want %q", got, longID)
}
if got := fullTableOutputWithTTY(false, false); !got {
t.Fatalf("non-TTY should request full output")
}
if got := truncateForDisplay(longID, 14, false); got != "3EB0B0E8A1B2C…" {
if got := tableCell(longID, 14, false); got != "3EB0B0E8A1B2C…" {
t.Fatalf("tty truncation = %q", got)
}
}

17
cmd/wacli/table.go Normal file
View File

@ -0,0 +1,17 @@
package main
import (
"io"
"text/tabwriter"
)
func newTableWriter(dst io.Writer) *tabwriter.Writer {
return tabwriter.NewWriter(dst, 2, 4, 2, ' ', 0)
}
func tableCell(s string, max int, full bool) string {
if full {
return sanitize(s)
}
return truncate(s, max)
}