Description
gws gmail +reply (without --html) corrupts the quoted parent message when the original body has hard-wrapped lines that, after the > prefix is added, exceed 76 characters. The quoted-printable encoder soft-wraps each oversized line with =\r\n. Because the next line of the source body also carries its own > prefix, after QP decoding the result has > injected mid-content. This (a) corrupts the visible quoting and (b) prevents Gmail's "show trimmed content" collapse from matching the parent text, so the full quoted history stays expanded inline.
This is closely related to #567, which was closed as not-reproducible. The repro there used a short single-line message that didn't trigger QP soft-wrapping. The bug is still present at main HEAD for any parent with hard-wrapped lines around 70-75 chars (very common — most email clients wrap there).
Steps to reproduce
-
Receive an email whose body is hard-wrapped at ~70-75 chars per line (a recruiter cold-outreach is a reliable trigger).
-
gws gmail +reply --message-id <id> --draft --body "Short reply."
-
Open the draft in Gmail web. The "show trimmed content" collapse does not fire; quoted history is fully expanded.
-
Inspect the raw MIME via users.drafts.get --params '{"userId":"me","id":"<draft-id>","format":"raw"}' and look for sequences like:
> access infrastructure that connects patients to great care. This role sits=
> at the center of that expansion.
After QP decoding, the soft break joins those lines into > access ... sits> at the center — > injected mid-content where the original had a single space.
Root cause
In crates/google-workspace-cli/src/helpers/gmail/reply.rs, format_quoted_original prefixes each line of body_text with > and joins. Any prefixed line at >76 chars then gets QP-soft-wrapped downstream. Soft-break removal stitches together lines that each carry their own > prefix, so the decoded plain text contains spurious > mid-sentence.
Possible fixes
- Pre-wrap before prefixing — wrap
body_text to ≤73 chars/line so prefixed lines stay ≤75. Cleanest fix for plain-text mode.
- Encode the body as 8bit when 7-bit safe, sidestepping QP soft-wrapping.
- Default
+reply to HTML mode (or warn when plain-text quoting would cross 76 chars). HTML mode already produces Gmail-native <blockquote class="gmail_quote"> and dodges QP entirely.
Workaround
Pass --html to +reply and HTML-escape the body (convert newlines to <br>). The resulting <div class="gmail_quote gmail_quote_container"><blockquote class="gmail_quote"> is what Gmail-native replies emit, and Gmail collapses it correctly.
Environment
- gws:
main HEAD (a3768d0)
- OS: Ubuntu 24.04 (Linux 6.8)
Description
gws gmail +reply(without--html) corrupts the quoted parent message when the original body has hard-wrapped lines that, after the>prefix is added, exceed 76 characters. The quoted-printable encoder soft-wraps each oversized line with=\r\n. Because the next line of the source body also carries its own>prefix, after QP decoding the result has>injected mid-content. This (a) corrupts the visible quoting and (b) prevents Gmail's "show trimmed content" collapse from matching the parent text, so the full quoted history stays expanded inline.This is closely related to #567, which was closed as not-reproducible. The repro there used a short single-line message that didn't trigger QP soft-wrapping. The bug is still present at
mainHEAD for any parent with hard-wrapped lines around 70-75 chars (very common — most email clients wrap there).Steps to reproduce
Receive an email whose body is hard-wrapped at ~70-75 chars per line (a recruiter cold-outreach is a reliable trigger).
gws gmail +reply --message-id <id> --draft --body "Short reply."Open the draft in Gmail web. The "show trimmed content" collapse does not fire; quoted history is fully expanded.
Inspect the raw MIME via
users.drafts.get --params '{"userId":"me","id":"<draft-id>","format":"raw"}'and look for sequences like:After QP decoding, the soft break joins those lines into
> access ... sits> at the center—>injected mid-content where the original had a single space.Root cause
In
crates/google-workspace-cli/src/helpers/gmail/reply.rs,format_quoted_originalprefixes each line ofbody_textwith>and joins. Any prefixed line at >76 chars then gets QP-soft-wrapped downstream. Soft-break removal stitches together lines that each carry their own>prefix, so the decoded plain text contains spurious>mid-sentence.Possible fixes
body_textto ≤73 chars/line so prefixed lines stay ≤75. Cleanest fix for plain-text mode.+replyto HTML mode (or warn when plain-text quoting would cross 76 chars). HTML mode already produces Gmail-native<blockquote class="gmail_quote">and dodges QP entirely.Workaround
Pass
--htmlto+replyand HTML-escape the body (convert newlines to<br>). The resulting<div class="gmail_quote gmail_quote_container"><blockquote class="gmail_quote">is what Gmail-native replies emit, and Gmail collapses it correctly.Environment
mainHEAD (a3768d0)