Sometimes you need to ask notmuch for just a few messages, and notmuch supports that with date range options. Date ranges, however, are not sufficient for an application that is paging and just wants message x through y, then x+d through y+d, etc. And if you're sending the json results of a search to a client for rendering, it makes sense to just send the small ranges the client actually wants. This patch implements --initial-index and --last-index as options to search and show. It lets you select the xth through the yth message and receive results that pertain only to those messages. I did not enable this option for results specifying --output=tags since the output of a tag search isn't much data. --- notmuch-search.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ notmuch-show.c | 30 ++++++++++++++++++++++++++---- notmuch.1 | 32 ++++++++++++++++++++++++++++++++ notmuch.c | 18 +++++++++++++++++- 4 files changed, 117 insertions(+), 11 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index faccaf7..f7deb4a 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -194,7 +194,9 @@ static int do_search_threads (const search_format_t *format, notmuch_query_t *query, notmuch_sort_t sort, - output_t output) + output_t output, + int initial_thread, + int last_thread) { notmuch_thread_t *thread; notmuch_threads_t *threads; @@ -208,8 +210,15 @@ do_search_threads (const search_format_t *format, fputs (format->results_start, stdout); + last_thread -= initial_thread; + + for (; + initial_thread > 0 && notmuch_threads_valid (threads); + notmuch_threads_move_to_next (threads)) + initial_thread--; + for (; - notmuch_threads_valid (threads); + last_thread != 0 && notmuch_threads_valid (threads); notmuch_threads_move_to_next (threads)) { int first_tag = 1; @@ -258,6 +267,7 @@ do_search_threads (const search_format_t *format, first_thread = 0; notmuch_thread_destroy (thread); + last_thread--; } if (first_thread) @@ -271,7 +281,9 @@ do_search_threads (const search_format_t *format, static int do_search_messages (const search_format_t *format, notmuch_query_t *query, - output_t output) + output_t output, + int initial_message, + int last_message) { notmuch_message_t *message; notmuch_messages_t *messages; @@ -284,8 +296,15 @@ do_search_messages (const search_format_t *format, fputs (format->results_start, stdout); + last_message -= initial_message; + + for (; + initial_message > 0 && notmuch_messages_valid (messages); + notmuch_messages_move_to_next (messages)) + initial_message--; + for (; - notmuch_messages_valid (messages); + last_message != 0 && notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { message = notmuch_messages_get (messages); @@ -318,6 +337,7 @@ do_search_messages (const search_format_t *format, } notmuch_message_destroy (message); + last_message--; } notmuch_messages_destroy (messages); @@ -394,6 +414,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) const search_format_t *format = &format_text; int i, ret; output_t output = OUTPUT_SUMMARY; + int initial_index = 0; + int last_index = -1; for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (strcmp (argv[i], "--") == 0) { @@ -420,6 +442,16 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) fprintf (stderr, "Invalid value for --format: %s\n", opt); return 1; } + } else if (STRNCMP_LITERAL (argv[i], "--last-index=") == 0) { + opt = argv[i] + sizeof ("--last-index=") - 1; + last_index = atoi(opt); + if (last_index == 0) { + fprintf (stderr, "Last index set to 0.\n"); + return 1; + } + } else if (STRNCMP_LITERAL (argv[i], "--initial-index=") == 0) { + opt = argv[i] + sizeof ("--initial-index=") - 1; + initial_index = atoi(opt); } else if (STRNCMP_LITERAL (argv[i], "--output=") == 0) { opt = argv[i] + sizeof ("--output=") - 1; if (strcmp (opt, "summary") == 0) { @@ -476,13 +508,17 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) default: case OUTPUT_SUMMARY: case OUTPUT_THREADS: - ret = do_search_threads (format, query, sort, output); + ret = do_search_threads (format, query, sort, output, initial_index, last_index); break; case OUTPUT_MESSAGES: case OUTPUT_FILES: - ret = do_search_messages (format, query, output); + ret = do_search_messages (format, query, output, initial_index, last_index); break; case OUTPUT_TAGS: + if (initial_index != 0 || last_index != -1) { + fprintf(stderr, "--initial-index and --last-index are not supported for searching tags\n"); + return 1; + } ret = do_search_tags (notmuch, format, query); break; } diff --git a/notmuch-show.c b/notmuch-show.c index fb74300..097557b 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -813,7 +813,9 @@ static int do_show (void *ctx, notmuch_query_t *query, const notmuch_show_format_t *format, - notmuch_show_params_t *params) + notmuch_show_params_t *params, + int initial_thread, + int last_thread) { notmuch_threads_t *threads; notmuch_thread_t *thread; @@ -822,9 +824,16 @@ do_show (void *ctx, fputs (format->message_set_start, stdout); + last_thread -= initial_thread; for (threads = notmuch_query_search_threads (query); - notmuch_threads_valid (threads); - notmuch_threads_move_to_next (threads)) + initial_thread > 0 && notmuch_threads_valid (threads); + notmuch_threads_move_to_next (threads)) + initial_thread--; + + for (//threads = notmuch_query_search_threads (query) + ; + last_thread !=0 && notmuch_threads_valid (threads); + notmuch_threads_move_to_next (threads)) { thread = notmuch_threads_get (threads); @@ -842,6 +851,7 @@ do_show (void *ctx, notmuch_thread_destroy (thread); + last_thread--; } fputs (format->message_set_end, stdout); @@ -862,6 +872,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) int mbox = 0; int format_specified = 0; int i; + int last_index = -1; + int initial_index = 0; params.entire_thread = 0; params.raw = 0; @@ -892,6 +904,16 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) return 1; } format_specified = 1; + } else if (STRNCMP_LITERAL (argv[i], "--last-index=") == 0) { + opt = argv[i] + sizeof ("--last-index=") - 1; + last_index = atoi(opt); + if (last_index == 0) { + fprintf (stderr, "Last index set to 0.\n"); + return 1; + } + } else if (STRNCMP_LITERAL (argv[i], "--initial-index=") == 0) { + opt = argv[i] + sizeof ("--initial-index=") - 1; + initial_index = atoi(opt); } else if (STRNCMP_LITERAL (argv[i], "--part=") == 0) { params.part = atoi(argv[i] + sizeof ("--part=") - 1); } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) { @@ -961,7 +983,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) if (params.part >= 0) return do_show_single (ctx, query, format, ¶ms); else - return do_show (ctx, query, format, ¶ms); + return do_show (ctx, query, format, ¶ms, initial_index, last_index); notmuch_query_destroy (query); notmuch_database_close (notmuch); diff --git a/notmuch.1 b/notmuch.1 index 5a8c83d..2abc8aa 100644 --- a/notmuch.1 +++ b/notmuch.1 @@ -153,6 +153,22 @@ Presents the results in either JSON or plain-text (default). .RS 4 .TP 4 +.B \-\-initial-thread=N + +Starts presenting results with the Nth result. This option does not +apply if output=tags. +.RE + +.RS 4 +.TP 4 +.B \-\-last-thread=N + +Stops presenting results with the Nth result (counting from 0, not +from the initial index). This option does not apply if output=tags. +.RE + +.RS 4 +.TP 4 .B \-\-output=(summary|threads|messages|files|tags) .RS 4 @@ -313,6 +329,22 @@ message. .RS 4 .TP 4 +.B \-\-initial-thread=N + +Starts presenting results with the Nth result. This option does not +apply if output=tags. +.RE + +.RS 4 +.TP 4 +.B \-\-last-thread=N + +Stops presenting results with the Nth result (counting from 0, not +from the initial index). This option does not apply if output=tags. +.RE + +.RS 4 +.TP 4 .B \-\-part=N Output the single decoded MIME part N of a single message. The search diff --git a/notmuch.c b/notmuch.c index 3973e35..55f712c 100644 --- a/notmuch.c +++ b/notmuch.c @@ -183,6 +183,17 @@ static command_t commands[] = { "\t\tPresents the results in either JSON or\n" "\t\tplain-text (default)\n" "\n" + "\t--initial-index=N\n" + "\n" + "\t\tStarts presenting results from the Nth result. This\n" + "\t\toption does not apply if output=tags.\n" + "\n" + "\t--last-index=N\n" + "\n" + "\t\tStops presenting results with the Nth result (counting\n" + "\t\tfrom 0, not from the initial index). This option does\n" + "\t\tnot apply if output=tags.\n" + "\n" "\t--output=(summary|threads|messages|files|tags)\n" "\n" "\t\tsummary (default)\n" @@ -223,7 +234,8 @@ static command_t commands[] = { "\t\t(newest-first), which is the default.\n" "\n" "\tSee \"notmuch help search-terms\" for details of the search\n" - "\tterms syntax." }, + "\tterms syntax." + "\n"}, { "show", notmuch_show_command, "<search-terms> [...]", "Show all messages matching the search terms.", @@ -286,6 +298,10 @@ static command_t commands[] = { "\t\tThe raw format must only be used with search terms matching\n" "\t\tsingle message.\n" "\n" + "\t--last-thread=N\n" + "\n" + "\t\tPresents results up until thread number N.\n" + "\n" "\t--part=N\n" "\n" "\t\tOutput the single decoded MIME part N of a single message.\n" -- 1.7.5.4