From: Tomi Ollila <tomi.ollila@iki.fi>
To: Robin Jarry <robin@jarry.cc>, notmuch@notmuchmail.org
Cc: Robin Jarry <robin@jarry.cc>, Tim Culverhouse <tim@timculverhouse.com>
Subject: Re: [PATCH] cli: add options --offset and --limit to notmuch show
Date: Wed, 12 Oct 2022 22:39:50 +0300 [thread overview]
Message-ID: <y3a23ky.1t6gr8-too@iki.fi> (raw)
In-Reply-To: <20221011221942.341732-1-robin@jarry.cc>
On Wed, Oct 12 2022, Robin Jarry wrote:
> notmuch search does not output header values. However, when browsing
> through a large email corpus, it can be time saving to be able to
> paginate without running notmuch show for each message/thread.
>
> Add --offset and --limit options to notmuch show. This is inspired from
> commit 796b629c3b82 ("cli: add options --offset and --limit to notmuch
> search").
>
> Update man page, shell completion and add a test case to ensure it works
> as expected.
>
> Cc: Tim Culverhouse <tim@timculverhouse.com>
> Signed-off-by: Robin Jarry <robin@jarry.cc>
> ---
> completion/notmuch-completion.bash | 2 +-
> completion/zsh/_notmuch | 2 +
> doc/man1/notmuch-show.rst | 9 ++++
> notmuch-client.h | 2 +
> notmuch-show.c | 49 +++++++++++++++---
> test/T131-show-limiting.sh | 81 ++++++++++++++++++++++++++++++
> 6 files changed, 138 insertions(+), 7 deletions(-)
> create mode 100755 test/T131-show-limiting.sh
>
> diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
> index 0022b54bff5d..3748846edf83 100644
> --- a/completion/notmuch-completion.bash
> +++ b/completion/notmuch-completion.bash
> @@ -530,7 +530,7 @@ _notmuch_show()
> ! $split &&
> case "${cur}" in
> -*)
> - local options="--entire-thread= --format= --exclude= --body= --format-version= --part= --verify --decrypt= --include-html ${_notmuch_shared_options}"
> + local options="--entire-thread= --format= --exclude= --body= --format-version= --part= --verify --decrypt= --include-html --limit= --offset= ${_notmuch_shared_options}"
> compopt -o nospace
> COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
> ;;
> diff --git a/completion/zsh/_notmuch b/completion/zsh/_notmuch
> index e207d90b7202..0bdd7f772a7a 100644
> --- a/completion/zsh/_notmuch
> +++ b/completion/zsh/_notmuch
> @@ -245,6 +245,8 @@ _notmuch_show() {
> '--exclude=[respect excluded tags setting]:exclude tags:(true false)' \
> '--body=[output body]:output body content:(true false)' \
> '--include-html[include text/html parts in the output]' \
> + '--limit=[limit the number of displayed results]:limit: ' \
> + '--offset=[skip displaying the first N results]:offset: ' \
> '*::search term:_notmuch_search_term'
> }
>
> diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
> index 2c0a0de6ad16..c13d94de0244 100644
> --- a/doc/man1/notmuch-show.rst
> +++ b/doc/man1/notmuch-show.rst
> @@ -130,6 +130,15 @@ Supported options for **show** include
> By default, results will be displayed in reverse chronological
> order, (that is, the newest results will be displayed first).
>
> +.. option:: --offset=[-]N
> +
> + Skip displaying the first N results. With the leading '-', start
> + at the Nth result from the end.
> +
> +.. option:: --limit=N
> +
> + Limit the number of displayed results to N.
> +
> .. option:: --verify
>
> Compute and report the validity of any MIME cryptographic
> diff --git a/notmuch-client.h b/notmuch-client.h
> index 21b49908ae24..1a87240d3c21 100644
> --- a/notmuch-client.h
> +++ b/notmuch-client.h
> @@ -77,6 +77,8 @@ typedef struct notmuch_show_params {
> bool output_body;
> int duplicate;
> int part;
> + int offset;
> + int limit;
> _notmuch_crypto_t crypto;
> bool include_html;
> GMimeStream *out_stream;
> diff --git a/notmuch-show.c b/notmuch-show.c
> index ee9efa7448d7..ad31e0123268 100644
> --- a/notmuch-show.c
> +++ b/notmuch-show.c
> @@ -1159,6 +1159,18 @@ do_show_threaded (void *ctx,
> notmuch_thread_t *thread;
> notmuch_messages_t *messages;
> notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
> + int i;
> +
> + if (params->offset < 0) {
> + unsigned count;
> + notmuch_status_t s = notmuch_query_count_threads (query, &count);
> + if (print_status_query ("notmuch search", query, s))
> + return 1;
> +
> + params->offset += count;
> + if (params->offset < 0)
this check and setting it to 0 is mystic to me, probably same code as in
search (?) probably it is good (?) (will not comment the same below)
> + params->offset = 0;
> + }
>
> status = notmuch_query_search_threads (query, &threads);
> if (print_status_query ("notmuch show", query, status))
> @@ -1166,11 +1178,16 @@ do_show_threaded (void *ctx,
>
> sp->begin_list (sp);
>
> - for (;
> - notmuch_threads_valid (threads);
> - notmuch_threads_move_to_next (threads)) {
> + for (i = 0;
> + notmuch_threads_valid (threads) && (params->limit < 0 || i < params->offset + params->limit);
> + notmuch_threads_move_to_next (threads), i++) {
> thread = notmuch_threads_get (threads);
>
> + if (i < params->offset) {
> + notmuch_thread_destroy (thread);
> + continue;
> + }
> +
> messages = notmuch_thread_get_toplevel_messages (thread);
>
> if (messages == NULL)
> @@ -1201,6 +1218,18 @@ do_show_unthreaded (void *ctx,
> notmuch_message_t *message;
> notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
> notmuch_bool_t excluded;
> + int i;
> +
> + if (params->offset < 0) {
> + unsigned count;
> + notmuch_status_t s = notmuch_query_count_messages (query, &count);
> + if (print_status_query ("notmuch search", query, s))
> + return 1;
> +
> + params->offset += count;
> + if (params->offset < 0)
> + params->offset = 0;
> + }
>
> status = notmuch_query_search_messages (query, &messages);
> if (print_status_query ("notmuch show", query, status))
> @@ -1208,9 +1237,13 @@ do_show_unthreaded (void *ctx,
>
> sp->begin_list (sp);
>
> - for (;
> - notmuch_messages_valid (messages);
> - notmuch_messages_move_to_next (messages)) {
> + for (i = 0;
> + notmuch_messages_valid (messages) && (params->limit < 0 || i < params->offset + params->limit);
> + notmuch_messages_move_to_next (messages), i++) {
> + if (i < params->offset) {
> + continue;
> + }
> +
> sp->begin_list (sp);
> sp->begin_list (sp);
>
> @@ -1287,6 +1320,8 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
> notmuch_show_params_t params = {
> .part = -1,
> .duplicate = 0,
> + .offset = 0,
> + .limit = -1, /* unlimited */
> .omit_excluded = true,
> .output_body = true,
> .crypto = { .decrypt = NOTMUCH_DECRYPT_AUTO },
> @@ -1328,6 +1363,8 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
> { .opt_bool = ¶ms.output_body, .name = "body" },
> { .opt_bool = ¶ms.include_html, .name = "include-html" },
> { .opt_int = ¶ms.duplicate, .name = "duplicate" },
> + { .opt_int = ¶ms.limit, .name = "limit" },
> + { .opt_int = ¶ms.offset, .name = "offset" },
> { .opt_inherit = notmuch_shared_options },
> { }
> };
> diff --git a/test/T131-show-limiting.sh b/test/T131-show-limiting.sh
> new file mode 100755
> index 000000000000..a3da35944a3e
> --- /dev/null
> +++ b/test/T131-show-limiting.sh
> @@ -0,0 +1,81 @@
> +#!/usr/bin/env bash
> +test_description='"notmuch show" --offset and --limit parameters'
> +. $(dirname "$0")/test-lib.sh || exit 1
> +
> +add_email_corpus
> +
> +function show() {
'function' not used in other function defitions in other files, so this is
inconsistent (otherwise the content looks "better" than what I see usual ;D)
> + local kind="$1"
> + shift
> + if [ "$kind" = messages ]; then
> + set -- --unthreaded "$@"
> + fi
> + notmuch show --body=false --format=text --entire-thread=false "$@" "*" |
> + sed -nre 's/^.message\{.*\<depth:0\>.*/&/p'
> +}
> +
> +for outp in messages threads; do
> + test_begin_subtest "$outp: limit does the right thing"
> + show $outp | head -n 20 >expected
> + show $outp --limit=20 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "$outp: concatenation of limited shows"
> + show $outp | head -n 20 >expected
> + show $outp --limit=10 >output
> + show $outp --limit=10 --offset=10 >>output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "$outp: limit larger than result set"
> + N=$(notmuch count --output=$outp "*")
> + show $outp >expected
> + show $outp --limit=$((1 + N)) >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "$outp: limit = 0"
> + test_expect_equal "$(show $outp --limit=0)" ""
> +
> + test_begin_subtest "$outp: offset does the right thing"
> + # note: tail -n +N is 1-based
> + show $outp | tail -n +21 >expected
> + show $outp --offset=20 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "${outp}: offset = 0"
inconsistent ${outp} (where $outp used elsewhere) ...
> + show $outp >expected
> + show $outp --offset=0 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "${outp}: negative offset"
> + show $outp | tail -n 20 >expected
> + show $outp --offset=-20 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "${outp}: negative offset"
> + show $outp | tail -n 1 >expected
> + show $outp --offset=-1 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "${outp}: negative offset combined with limit"
> + show $outp | tail -n 20 | head -n 10 >expected
> + show $outp --offset=-20 --limit=10 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "${outp}: negative offset combined with equal limit"
> + show $outp | tail -n 20 >expected
> + show $outp --offset=-20 --limit=20 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "${outp}: negative offset combined with large limit"
> + show $outp | tail -n 20 >expected
> + show $outp --offset=-20 --limit=50 >output
> + test_expect_equal_file expected output
> +
> + test_begin_subtest "${outp}: negative offset larger than results"
> + N=$(notmuch count --output=$outp "*")
> + show $outp >expected
> + show $outp --offset=-$((1 + N)) >output
> + test_expect_equal_file expected output
> +done
> +
> +test_done
> --
> 2.37.3
next prev parent reply other threads:[~2022-10-12 19:39 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-11 22:19 [PATCH] cli: add options --offset and --limit to notmuch show Robin Jarry
2022-10-11 22:25 ` Robin Jarry
2022-10-12 19:39 ` Tomi Ollila [this message]
2022-10-12 20:02 ` Robin Jarry
2022-10-14 8:16 ` Tomi Ollila
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://notmuchmail.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=y3a23ky.1t6gr8-too@iki.fi \
--to=tomi.ollila@iki.fi \
--cc=notmuch@notmuchmail.org \
--cc=robin@jarry.cc \
--cc=tim@timculverhouse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhetil.org/notmuch.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).