! $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}) )
;;
'--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'
}
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
bool output_body;
int duplicate;
int part;
+ int offset;
+ int limit;
_notmuch_crypto_t crypto;
bool include_html;
GMimeStream *out_stream;
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 show", query, s))
+ return 1;
+
+ params->offset += count;
+ if (params->offset < 0)
+ params->offset = 0;
+ }
status = notmuch_query_search_threads (query, &threads);
if (print_status_query ("notmuch show", query, status))
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)
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 show", 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))
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);
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 },
{ .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 },
{ }
};
--- /dev/null
+#!/usr/bin/env bash
+test_description='"notmuch show" --offset and --limit parameters'
+. $(dirname "$0")/test-lib.sh || exit 1
+
+add_email_corpus
+
+show () {
+ 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"
+ 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