--- /dev/null
+Return-Path: <dme@dme.org>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id F17DA431FC9\r
+ for <notmuch@notmuchmail.org>; Fri, 31 Oct 2014 00:14:27 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.699\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.699 tagged_above=-999 required=5\r
+ tests=[RCVD_IN_DNSWL_LOW=-0.7, UNPARSEABLE_RELAY=0.001]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id k2rIsqwhffje for <notmuch@notmuchmail.org>;\r
+ Fri, 31 Oct 2014 00:14:23 -0700 (PDT)\r
+Received: from mail-wg0-f50.google.com (mail-wg0-f50.google.com\r
+ [74.125.82.50]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client\r
+ certificate requested) by olra.theworths.org (Postfix) with ESMTPS id\r
+ 04C56431FC2 for <notmuch@notmuchmail.org>; Fri, 31 Oct 2014 00:14:22 -0700\r
+ (PDT)\r
+Received: by mail-wg0-f50.google.com with SMTP id z12so5843488wgg.37\r
+ for <notmuch@notmuchmail.org>; Fri, 31 Oct 2014 00:14:21 -0700 (PDT)\r
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
+ d=1e100.net; s=20130820;\r
+ h=x-gm-message-state:to:cc:subject:in-reply-to:references:user-agent\r
+ :from:date:message-id:mime-version:content-type;\r
+ bh=hiwImRarpvFxXOWeS2hEoAFdCUA1y6KBdcJBqNRqylc=;\r
+ b=Fr5KCKN8D15tz/AAFdvwFpS6jMsR2wVyK3435zr4GcRgnZwl8u6XQcuPJ9xYKIpm1t\r
+ k9bNJxxKubhQkSEs5RrfdimU0FAG3IMgAakFohh1JsM6enGSLNS7yR2pgZ6z2o0LEMsp\r
+ y2xUDL3w2sECmVpDxNpLNphE6Ee3E8D7Ay9NnDSmHo00Y3uC0+Wy+mtKm4jQY6T5k26N\r
+ bKjVuEDwA+lwgmW9g+EdaGJIdHw4aSuhWPcmqzPyb66wPKVUe50wtBHKxXFrWgRuRQ7Q\r
+ dmqTawqqj0/52qNuXZZ334M8ctm+FzC0Rj+852qVvJaTGf1UExuXsUkXcSqGMCFhliPs\r
+ FPLQ==\r
+X-Gm-Message-State:\r
+ ALoCoQnEFcyed5LDey0yX8vCqBXsto7qjHfgtsuNkIkncPBcYTTgCVBls74vrS+Q/P3IkCtn0goT\r
+X-Received: by 10.180.39.106 with SMTP id o10mr1934064wik.54.1414739661654;\r
+ Fri, 31 Oct 2014 00:14:21 -0700 (PDT)\r
+Received: from disaster-area.hh.sledj.net\r
+ ([2a01:348:1a2:1:ea39:35ff:fe2c:a227])\r
+ by mx.google.com with ESMTPSA id cu9sm11101834wjc.3.2014.10.31.00.14.20\r
+ for <multiple recipients>\r
+ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\r
+ Fri, 31 Oct 2014 00:14:20 -0700 (PDT)\r
+Received: from localhost (30000@localhost [local]);\r
+ by localhost (OpenSMTPD) with ESMTPA id 850adb90;\r
+ Fri, 31 Oct 2014 07:14:19 +0000 (UTC)\r
+To: Jani Nikula <jani@nikula.org>, notmuch@notmuchmail.org\r
+Subject: Re: [PATCH] cli: add support for notmuch search --duplicate=N with\r
+ --output=messages\r
+In-Reply-To: <1414705489-30771-1-git-send-email-jani@nikula.org>\r
+References: <m28ujy6kba.fsf@dme.org>\r
+ <1414705489-30771-1-git-send-email-jani@nikula.org>\r
+User-Agent: Notmuch/0.18.1 (http://notmuchmail.org) Emacs/24.3.1\r
+ (x86_64-apple-darwin14.0.0)\r
+From: David Edmondson <dme@dme.org>\r
+Date: Fri, 31 Oct 2014 07:14:19 +0000\r
+Message-ID: <m27fzg6790.fsf@heart-of-gold.hh.sledj.net>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Fri, 31 Oct 2014 07:14:28 -0000\r
+\r
+On Thu, Oct 30 2014, Jani Nikula wrote:\r
+> Print the message IDs of all messages matching the search terms that\r
+> have at least N files associated with them.\r
+\r
+Briefly tested as working. I commend this patch to the masters of push.\r
+\r
+Thanks Jani!\r
+\r
+> ---\r
+> doc/man1/notmuch-search.rst | 12 ++++++++----\r
+> notmuch-search.c | 34 ++++++++++++++++++++++++++++++----\r
+> 2 files changed, 38 insertions(+), 8 deletions(-)\r
+>\r
+> diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst\r
+> index 90160f21e23c..aeba4bf604f6 100644\r
+> --- a/doc/man1/notmuch-search.rst\r
+> +++ b/doc/man1/notmuch-search.rst\r
+> @@ -122,10 +122,14 @@ Supported options for **search** include\r
+> rather than the number of matching messages.\r
+> \r
+> ``--duplicate=N``\r
+> - Effective with ``--output=files``, output the Nth filename\r
+> - associated with each message matching the query (N is 1-based).\r
+> - If N is greater than the number of files associated with the\r
+> - message, don't print anything.\r
+> + For ``--output=files``, output the Nth filename associated\r
+> + with each message matching the query (N is 1-based). If N is\r
+> + greater than the number of files associated with the message,\r
+> + don't print anything.\r
+> +\r
+> + For ``--output=messages``, only output message IDs of messages\r
+> + matching the search terms that have at least N filenames\r
+> + associated with them.\r
+> \r
+> Note that this option is orthogonal with the **folder:** search\r
+> prefix. The prefix matches messages based on filenames. This\r
+> diff --git a/notmuch-search.c b/notmuch-search.c\r
+> index bc9be4593ecc..2bf876fd5abf 100644\r
+> --- a/notmuch-search.c\r
+> +++ b/notmuch-search.c\r
+> @@ -215,6 +215,24 @@ do_search_threads (sprinter_t *format,\r
+> }\r
+> \r
+> static int\r
+> +_count_filenames (notmuch_message_t *message)\r
+> +{\r
+> + notmuch_filenames_t *filenames;\r
+> + int i = 0;\r
+> +\r
+> + filenames = notmuch_message_get_filenames (message);\r
+> +\r
+> + while (notmuch_filenames_valid (filenames)) {\r
+> + notmuch_filenames_move_to_next (filenames);\r
+> + i++;\r
+> + }\r
+> +\r
+> + notmuch_filenames_destroy (filenames);\r
+> +\r
+> + return i;\r
+> +}\r
+> +\r
+> +static int\r
+> do_search_messages (sprinter_t *format,\r
+> notmuch_query_t *query,\r
+> output_t output,\r
+> @@ -265,10 +283,13 @@ do_search_messages (sprinter_t *format,\r
+> notmuch_filenames_destroy( filenames );\r
+> \r
+> } else { /* output == OUTPUT_MESSAGES */\r
+> - format->set_prefix (format, "id");\r
+> - format->string (format,\r
+> - notmuch_message_get_message_id (message));\r
+> - format->separator (format);\r
+> + /* special case 1 for speed */\r
+> + if (dupe <= 1 || dupe <= _count_filenames (message)) {\r
+> + format->set_prefix (format, "id");\r
+> + format->string (format,\r
+> + notmuch_message_get_message_id (message));\r
+> + format->separator (format);\r
+> + }\r
+> }\r
+> \r
+> notmuch_message_destroy (message);\r
+> @@ -387,6 +408,11 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])\r
+> if (opt_index < 0)\r
+> return EXIT_FAILURE;\r
+> \r
+> + if (output != OUTPUT_FILES && output != OUTPUT_MESSAGES && dupe != -1) {\r
+> + fprintf (stderr, "Error: --duplicate=N is only supported with --output=files and --output=messages.\n");\r
+> + return EXIT_FAILURE;\r
+> + }\r
+> +\r
+> switch (format_sel) {\r
+> case NOTMUCH_FORMAT_TEXT:\r
+> format = sprinter_text_create (config, stdout);\r
+> -- \r
+> 2.1.1\r