From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id 4B97IDiC4WAF0AAAgWs5BA (envelope-from ) for ; Sun, 04 Jul 2021 11:41:12 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2 with LMTPS id mHgeHDiC4WAvFAAAB5/wlQ (envelope-from ) for ; Sun, 04 Jul 2021 09:41:12 +0000 Received: from mail.notmuchmail.org (nmbug.tethera.net [144.217.243.247]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id C12931E353 for ; Sun, 4 Jul 2021 11:41:11 +0200 (CEST) Received: from nmbug.tethera.net (localhost [127.0.0.1]) by mail.notmuchmail.org (Postfix) with ESMTP id CE60B2904D; Sun, 4 Jul 2021 05:41:06 -0400 (EDT) Received: from lahtoruutu.iki.fi (lahtoruutu.iki.fi [IPv6:2a0b:5c81:1c1::37]) by mail.notmuchmail.org (Postfix) with ESMTPS id 5876C26C01 for ; Sun, 4 Jul 2021 05:41:04 -0400 (EDT) Received: from guru.guru-group.fi (unknown [IPv6:2a02:2380:1:9:5054:ff:feb7:a4bc]) (using TLSv1.2 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: too) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 1367C1B001CF; Sun, 4 Jul 2021 12:41:01 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1625391661; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=cNo4fGnEV02FNClitGIRDzoxcKJlPQPIQrgoLRUQeH4=; b=BNX0LvMGUTFk+Iblnlej+KyItzsU/7eA8ijyRYmpd1Jc7NZEi+A/h59FQf5kMM8aiDCdWR K4738NtTo6xVC84FhjbUlzZROmo6G516OIWcDVH5tNbUKxcg/Q0KWylhf3xNjECeo0KS4n W56DL90uvvRl0nAPul9KfDHmobRi3Mm+oywz/ER3rAOzlCUkRzDzVwXHm7hBFnCHdD06L4 xu7sbVpRQvIoVd88gYxOwLrE21JMxb7k7pk0DX6iifgwDJRjOIiSxGNbBmOJFxMGyn0V9c L7Hh3dhBzHfnnrAwo9w8Uiq01OpSrethBji3YwDbCe16BmTGqamYIKDwzTfaUg== From: Tomi Ollila To: Hannu Hartikainen , notmuch@notmuchmail.org Subject: Re: [PATCH v2] cli/show: add --format=pretty In-Reply-To: <20210702203153.47289-1-hannu@hrtk.in> References: <20210619203838.275767-1-hannu@hrtk.in> <20210702203153.47289-1-hannu@hrtk.in> User-Agent: Notmuch/0.32+21~gfdddd4c (https://notmuchmail.org) Emacs/27.1 X-Face: HhBM'cA~ MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1625391661; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=cNo4fGnEV02FNClitGIRDzoxcKJlPQPIQrgoLRUQeH4=; b=cnoMLbJGxTHubFUNzhM8VOF9P7tb6j7AOekXXjEGg0Wwiw8znHhwI6Zdx4mtm2ahSL45RA YRlwX38JFbSTN3Fj6pC/OUfmwsFSlDkmMQwsKh40yjNLXtLSj+ciUPtWXUxdE98MU98ffW P0S9kaQWE57KCbXKKl0KBba+58wRub8IlkkK7Hwx39rw4w3WmiAzFafX5VZwLjsQvFYV/0 BNsNZ7+eG0OfU44WWIGAYr2/VbbyTIewO2ZuG8jITJZxape4NBRQyVPIqg1iOZ6wa3/pMc gwUq59Wdu4PNTYrjBIfdmU/dDKk/yw5QwgGPJywtNRO3bycCRcZ1P6hnzg4Aqw== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=too smtp.mailfrom=tomi.ollila@iki.fi ARC-Seal: i=1; s=lahtoruutu; d=iki.fi; t=1625391661; a=rsa-sha256; cv=none; b=kTMU4MQvWcz9H3i1pQQZihkJkK1wiezkl/BZh/3d4EAa9uw95EJCA0Kr+OC0E0KeK4PtPy TYCWKuWNDtjQp8Hys67EARR8YfcNlY+E5LbN69cXdBtwrEGbbjsiH0DYwqtp0yhLADV/9D n6Hw6NK/6W8t5ERzvSMaezZEzvjuipZULzkA/WgOiIOI5H24JnDGQanI1RrwRUdpVRD9jw oyCnC9YKDbTlj5q5xJ7wfKkCkc7NwZ1r/n1y/MHwaknuTddqVtpNlcuvs9VQCJCo5E1nrO ZpcDGwO2U8r9yxOR/qnazGDhFDQpYwFuNVhTsEONaM14vpG9vVp/YShRVTNzPA== Message-ID-Hash: GXGF5ZXVMQMKR2C3SJBB7IYKK6BJIPVK X-Message-ID-Hash: GXGF5ZXVMQMKR2C3SJBB7IYKK6BJIPVK X-MailFrom: tomi.ollila@iki.fi X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-notmuch.notmuchmail.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Hannu Hartikainen X-Mailman-Version: 3.2.1 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1625391672; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=NouUxvIQc2UoZR7dr5ZJCEM9ypagUESWER5lqui80E8=; b=oSXSG5LyLULC9vW1MRqoFTCV5TYa+geXQR0pd6J8vx+T5EWJ5/MF7+dGS8hEFOYvmFBey8 41tSX9+hk0MlDB1j9sWVAcm19ioN4EONJ5BjXVC9iELs+B21b0ZGN23D2Kk734TbkbwTi+ wZgUBC3r5BLsC6XgUslsZOP80WCOhX13hyU9/Qc5dd4EFoW8Knw5h6UIZpdWGd9XukVoUX rM+UBP5kUG+5inyOnw6wN1CoeOhAS9M+2b7pvvXfcO2xO4JziboZOf1cMou1HApRqaG1UI +T5AGWD/ofDU4yFrNmYHfD774Yo4op+AHnabHirpy45SzZ7KsWFDtbb3WFnyaQ== ARC-Seal: i=2; s=key1; d=yhetil.org; t=1625391672; a=rsa-sha256; cv=fail; b=ZXUScVNaBt6T2/sVNQvoe1WJbiapz3jtDcHx1kYqa46dxWz/wYreG9H0HJmk3Ho2ScHEeJ GQIgn5+hCJBoVA8MssB9yyLpOZJgmCmFcuAynGNinygboJxqjo+OGLip6YZBQh2dpYRzLf /fyppoxr733N7s8JsRXmh1JB3WD47tZwaVqxRwZL6vIlFRZQkfa0ESxDRixatp21brhUgy kZKE8iFnw9OBozAkB5rTxVHPIvjFXaTaOa2NuTFs4qdFdpjFVGazxgnEyi/e0km3UviOqL yNcDv75r0T7b1hKXsVTPIItVZNR4R92/J+4jxlhyBSz0hQmvJzfK7Zw9db/+hw== ARC-Authentication-Results: i=2; aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=iki.fi header.s=lahtoruutu header.b=BNX0LvMG; arc=reject ("signature check failed: fail, {[1] = sig:iki.fi:reject}"); dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 144.217.243.247 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Spam-Score: 0.94 Authentication-Results: aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=iki.fi header.s=lahtoruutu header.b=BNX0LvMG; arc=reject ("signature check failed: fail, {[1] = sig:iki.fi:reject}"); dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 144.217.243.247 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Queue-Id: C12931E353 X-Spam-Score: 0.94 X-Migadu-Scanner: scn1.migadu.com X-TUID: soPAIzJRAuQp On Fri, Jul 02 2021, Hannu Hartikainen wrote: > The rationale for this feature is twofold: > > 1. It is useful to be able to view messages in as human-friendly format > as possible. > 2. The same format should still be machine-readable, too. > > The email format is mostly human-readable as is. The things difficult > for a human eye are the huge amount of headers that are common these > days and telling different messages apart when there are many. > > This commit adds the display format `pretty`. It recognizes if the > output is a TTY and if so, applies coloring to headers. This turns out > to be a good visual message separator. Additionally it only shows the > most important headers, similarly to `--format=text`, and only displays > plaintext parts (ie. text/* but not text/html). > > While human readability is the main goal, another design goal was that > piping the output to `git am` works, at least for individual messages > sent with `git send-email`. > --- > > I wrote a v2 of this patch. I've been dogfooding for a while now and > wanted a couple of enhancements, and also had learned about the notmuch > test harness. The differences to the first version are: > > - add a unit test > - show Message-ID, making replying etc. much easier > - print a newline after each part, which helps a lot with messages that > do not end in a newline > > I'm using this as a daily driver and am happy with it. > > NEWS | 7 ++++ > completion/notmuch-completion.bash | 2 +- > completion/zsh/_notmuch | 2 +- > doc/man1/notmuch-show.rst | 8 +++- > notmuch-show.c | 67 ++++++++++++++++++++++++++++++ > test/T520-show.sh | 32 ++++++++++++++ > 6 files changed, 115 insertions(+), 3 deletions(-) > > diff --git a/NEWS b/NEWS > index 3e776009..f5142ff1 100644 > --- a/NEWS > +++ b/NEWS > @@ -1,6 +1,13 @@ > Notmuch 0.33 (UNRELEASED) > ========================= > > +CLI > +--- > + > +`notmuch show` now has `--format=pretty`, optimized for reading plain > +text emails on the command line. It only shows the most important > +headers and plain text parts and uses colors for headers. > + > Emacs > ----- > > diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash > index 15425697..86cbbcdc 100644 > --- a/completion/notmuch-completion.bash > +++ b/completion/notmuch-completion.bash > @@ -514,7 +514,7 @@ _notmuch_show() > return > ;; > --format) > - COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) ) > + COMPREPLY=( $( compgen -W "text pretty json sexp mbox raw" -- "${cur}" ) ) > return > ;; > --exclude|--body) > diff --git a/completion/zsh/_notmuch b/completion/zsh/_notmuch > index e920f10b..5cc386e2 100644 > --- a/completion/zsh/_notmuch > +++ b/completion/zsh/_notmuch > @@ -237,7 +237,7 @@ _notmuch_search() { > _notmuch_show() { > _arguments -S \ > '--entire-thread=[output entire threads]:show thread:(true false)' \ > - '--format=[set output format]:output format:(text json sexp mbox raw)' \ > + '--format=[set output format]:output format:(text pretty json sexp mbox raw)' \ > '--format-version=[set output format version]:format version: ' \ > '--part=[output a single decoded mime part]:part number: ' \ > '--verify[verify signed MIME parts]' \ > diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst > index fc6bec62..1fe4dcc7 100644 > --- a/doc/man1/notmuch-show.rst > +++ b/doc/man1/notmuch-show.rst > @@ -34,7 +34,7 @@ Supported options for **show** include > the matching messages. For ``--format=json`` and ``--format=sexp`` > this defaults to true. For other formats, this defaults to false. > > -.. option:: --format=(text|json|sexp|mbox|raw) > +.. option:: --format=(text|pretty|json|sexp|mbox|raw) > > **text** (default for messages) > The default plain-text format has all text-content MIME parts > @@ -46,6 +46,12 @@ Supported options for **show** include > '}'), to either open or close the component. For a multipart > MIME message, these parts will be nested. > > + **pretty** > + The plain-text parts of all matching messages are printed in a > + format optimized for readability. Only the most important > + headers are displayed. If the output is to a TTY, the headers > + are colored. > + > **json** > The output is formatted with Javascript Object Notation > (JSON). This format is more robust than the text format for > diff --git a/notmuch-show.c b/notmuch-show.c > index 232557d5..c417ec00 100644 > --- a/notmuch-show.c > +++ b/notmuch-show.c > @@ -606,6 +606,65 @@ format_part_text (const void *ctx, sprinter_t *sp, mime_node_t *node, > return NOTMUCH_STATUS_SUCCESS; > } > > +static notmuch_status_t > +format_part_pretty (const void *ctx, sprinter_t *sp, mime_node_t *node, > + int indent, const notmuch_show_params_t *params) > +{ > + /* The disposition and content-type metadata are associated with > + * the envelope for message parts */ > + GMimeObject *meta = node->envelope_part ? ( > + GMIME_OBJECT (node->envelope_part) ) : node->part; > + GMimeContentType *content_type = g_mime_object_get_content_type (meta); > + GMimeStream *stream = params->out_stream; > + int i; > + bool color = isatty (fileno (stdout)); > + > + if (GMIME_IS_MESSAGE (node->part)) { > + GMimeMessage *message = GMIME_MESSAGE (node->part); > + char *recipients_string; > + char *date_string; > + > + if (color) > + g_mime_stream_printf (stream, "\e[36m"); The code looks good to me, just that these "hardcoded" color values gives me a bit of suspicion... When running $ bash -c 'printf "\e[31m 31 \e[32m 32 \e[33m 33 \e[35m 35 \e[36m 36\n"' (use \033 instead of \e with dash(1)) the colors look OK when background is dark (black). on light background (white) color 33 (yellow), color 36 (cyan) and color 32 (green) are somewhat hard to read (in decreasing hardness)... I did not try to apply this and see how those looks like when displaying real emails (no setup on this machine for now...) Another thing is terminal support -- what if terminal did not have support for these escape sequences. Surprisingly that color testing worked OK in emacs shell (which claimed $TERM as 'dumb') if the option were '--ugly' -- then I would not have had any comments >;) One option would be to first send this without color support and then add *configurable* color support -- I don't know which way is better but as a rewiever that would be easier to accept... Tomi > + g_mime_stream_printf (stream, "Subject: %s\n", g_mime_message_get_subject (message)); > + if (color) > + g_mime_stream_printf (stream, "\e[33m"); > + g_mime_stream_printf (stream, "From: %s\n", g_mime_message_get_from_string (message)); > + if (color) > + g_mime_stream_printf (stream, "\e[31m"); > + recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_TO); > + if (recipients_string) > + g_mime_stream_printf (stream, "To: %s\n", recipients_string); > + g_free (recipients_string); > + recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_CC); > + if (recipients_string) > + g_mime_stream_printf (stream, "Cc: %s\n", recipients_string); > + g_free (recipients_string); > + date_string = g_mime_message_get_date_string (node, message); > + if (color) > + g_mime_stream_printf (stream, "\e[35m"); > + g_mime_stream_printf (stream, "Date: %s\n", date_string); > + if (color) > + g_mime_stream_printf (stream, "\e[32m"); > + g_mime_stream_printf (stream, "Message-ID: <%s>\n\n", g_mime_message_get_message_id ( > + message)); > + if (color) > + g_mime_stream_printf (stream, "\e[0m"); > + } > + > + if (GMIME_IS_PART (node->part) && > + g_mime_content_type_is_type (content_type, "text", "*") && > + ! g_mime_content_type_is_type (content_type, "text", "html")) { > + show_text_part_content (node->part, stream, 0); > + g_mime_stream_printf (stream, "\n"); > + } > + > + for (i = 0; i < node->nchildren; i++) > + format_part_pretty (ctx, sp, mime_node_child (node, i), indent, params); > + > + return NOTMUCH_STATUS_SUCCESS; > +} > + > static void > format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta, GMimePart *part) > { > @@ -1192,6 +1251,7 @@ enum { > NOTMUCH_FORMAT_JSON, > NOTMUCH_FORMAT_SEXP, > NOTMUCH_FORMAT_TEXT, > + NOTMUCH_FORMAT_PRETTY, > NOTMUCH_FORMAT_MBOX, > NOTMUCH_FORMAT_RAW > }; > @@ -1211,6 +1271,11 @@ static const notmuch_show_format_t format_text = { > .part = format_part_text, > }; > > +static const notmuch_show_format_t format_pretty = { > + .new_sprinter = sprinter_text_create, > + .part = format_part_pretty, > +}; > + > static const notmuch_show_format_t format_mbox = { > .new_sprinter = sprinter_text_create, > .part = format_part_mbox, > @@ -1225,6 +1290,7 @@ static const notmuch_show_format_t *formatters[] = { > [NOTMUCH_FORMAT_JSON] = &format_json, > [NOTMUCH_FORMAT_SEXP] = &format_sexp, > [NOTMUCH_FORMAT_TEXT] = &format_text, > + [NOTMUCH_FORMAT_PRETTY] = &format_pretty, > [NOTMUCH_FORMAT_MBOX] = &format_mbox, > [NOTMUCH_FORMAT_RAW] = &format_raw, > }; > @@ -1254,6 +1320,7 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) > { .opt_keyword = &format, .name = "format", .keywords = > (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON }, > { "text", NOTMUCH_FORMAT_TEXT }, > + { "pretty", NOTMUCH_FORMAT_PRETTY }, > { "sexp", NOTMUCH_FORMAT_SEXP }, > { "mbox", NOTMUCH_FORMAT_MBOX }, > { "raw", NOTMUCH_FORMAT_RAW }, > diff --git a/test/T520-show.sh b/test/T520-show.sh > index 16222650..e555b284 100755 > --- a/test/T520-show.sh > +++ b/test/T520-show.sh > @@ -10,4 +10,36 @@ notmuch show foo.. > exit_code=$? > test_expect_equal 1 $exit_code > > +test_begin_subtest "--format=pretty" > +output=$(notmuch show --format=pretty id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com 2>&1 && echo OK) > +test_expect_equal "$output" "Subject: [notmuch] preliminary FreeBSD support > +From: Alex Botero-Lowry > +To: notmuch@notmuchmail.org > +Date: Tue, 17 Nov 2009 11:36:14 -0800 > +Message-ID: > + > +I saw the announcement this morning, and was very excited, as I had been > +hoping sup would be turned into a library, > +since I like the concept more than the UI (I'd rather an emacs interface). > + > +I did a preliminary compile which worked out fine, but > +sysconf(_SC_SC_GETPW_R_SIZE_MAX) returns -1 on > +FreeBSD, so notmuch_config_open segfaulted. > + > +Attached is a patch that supplies a default buffer size of 64 in cases where > +-1 is returned. > + > +http://www.opengroup.org/austin/docs/austin_328.txt - seems to indicate this > +is acceptable behavior, > +and http://mail-index.netbsd.org/pkgsrc-bugs/2006/06/07/msg016808.htmlspecifically > +uses 64 as the > +buffer size. > + > +_______________________________________________ > +notmuch mailing list > +notmuch@notmuchmail.org > +http://notmuchmail.org/mailman/listinfo/notmuch > + > +OK" > + > test_done > -- > 2.32.0 > _______________________________________________ > notmuch mailing list -- notmuch@notmuchmail.org > To unsubscribe send an email to notmuch-leave@notmuchmail.org