From a86f77bfe563df0c628c0d78b09c7256e277d191 Mon Sep 17 00:00:00 2001 From: GodsBoy Date: Fri, 13 Mar 2026 09:35:09 +0200 Subject: [PATCH] feat(gmail): add --full flag to messages search to disable body truncation The --full flag skips the 200-character body truncation in plain-text output. It implies --include-body, so passing --full alone is enough. The gmail thread get command (gog gmail read) already had this flag; this brings parity to the messages search command. --- internal/cmd/gmail_messages.go | 11 +++++++++-- internal/cmd/gmail_messages_test.go | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/internal/cmd/gmail_messages.go b/internal/cmd/gmail_messages.go index 9e3ba1d9..2d59d83f 100644 --- a/internal/cmd/gmail_messages.go +++ b/internal/cmd/gmail_messages.go @@ -28,9 +28,13 @@ type GmailMessagesSearchCmd struct { Timezone string `name:"timezone" short:"z" help:"Output timezone (IANA name, e.g. America/New_York, UTC). Default: local"` Local bool `name:"local" help:"Use local timezone (default behavior, useful to override --timezone)"` IncludeBody bool `name:"include-body" help:"Include decoded message body (JSON is full; text output is truncated)"` + Full bool `name:"full" help:"Show full message bodies without truncation (implies --include-body)"` } func (c *GmailMessagesSearchCmd) Run(ctx context.Context, flags *RootFlags) error { + if c.Full { + c.IncludeBody = true + } u := ui.FromContext(ctx) account, err := requireAccount(flags) if err != nil { @@ -137,7 +141,7 @@ func (c *GmailMessagesSearchCmd) Run(ctx context.Context, flags *RootFlags) erro for _, it := range items { body := "" if c.IncludeBody { - body = sanitizeMessageBody(it.Body) + body = sanitizeMessageBody(it.Body, c.Full) } if c.IncludeBody { fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", it.ID, it.ThreadID, it.Date, it.From, it.Subject, strings.Join(it.Labels, ","), body) @@ -327,7 +331,7 @@ func fetchMessageDetails(ctx context.Context, svc *gmail.Service, messages []*gm return items, nil } -func sanitizeMessageBody(body string) string { +func sanitizeMessageBody(body string, full bool) string { if body == "" { return "" } @@ -338,6 +342,9 @@ func sanitizeMessageBody(body string) string { body = strings.ReplaceAll(body, "\n", " ") body = strings.ReplaceAll(body, "\r", " ") body = strings.TrimSpace(body) + if full { + return body + } return truncateRunes(body, 200) } diff --git a/internal/cmd/gmail_messages_test.go b/internal/cmd/gmail_messages_test.go index bcdf9a50..34b39511 100644 --- a/internal/cmd/gmail_messages_test.go +++ b/internal/cmd/gmail_messages_test.go @@ -15,7 +15,7 @@ import ( func TestSanitizeMessageBody_TruncateUTF8(t *testing.T) { long := strings.Repeat("€", 210) - got := sanitizeMessageBody(long) + got := sanitizeMessageBody(long, false) if !strings.HasSuffix(got, "...") { t.Fatalf("expected truncation suffix, got %q", got) } @@ -24,8 +24,19 @@ func TestSanitizeMessageBody_TruncateUTF8(t *testing.T) { } } +func TestSanitizeMessageBody_FullSkipsTruncation(t *testing.T) { + long := strings.Repeat("€", 210) + got := sanitizeMessageBody(long, true) + if strings.HasSuffix(got, "...") { + t.Fatalf("expected no truncation with full=true, got %q", got) + } + if len([]rune(got)) != 210 { + t.Fatalf("expected 210 runes, got %d", len([]rune(got))) + } +} + func TestSanitizeMessageBody_StripsHTML(t *testing.T) { - got := sanitizeMessageBody("Hi") + got := sanitizeMessageBody("Hi", false) if got != "Hi" { t.Fatalf("unexpected sanitized body: %q", got) }