--- /dev/null
+Return-Path: <stefanha@gmail.com>\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 A898F431FB6\r
+ for <notmuch@notmuchmail.org>; Tue, 9 Oct 2012 12:49:20 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.799\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.799 tagged_above=-999 required=5\r
+ tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+ FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7] 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 aWvFdWJmTwEG for <notmuch@notmuchmail.org>;\r
+ Tue, 9 Oct 2012 12:49:20 -0700 (PDT)\r
+Received: from mail-wg0-f45.google.com (mail-wg0-f45.google.com\r
+ [74.125.82.45]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client\r
+ certificate requested) by olra.theworths.org (Postfix) with ESMTPS id\r
+ C7E9F431FAF for <notmuch@notmuchmail.org>; Tue, 9 Oct 2012 12:49:19 -0700\r
+ (PDT)\r
+Received: by mail-wg0-f45.google.com with SMTP id dq12so4044646wgb.2\r
+ for <notmuch@notmuchmail.org>; Tue, 09 Oct 2012 12:49:17 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\r
+ h=from:to:cc:subject:date:message-id:x-mailer;\r
+ bh=eGTr6bXGDPR0O3B7tETppbKf3l0vR+T5gyfqvFsnriU=;\r
+ b=ca40/7bBhUaPitrkV5H4p1GpE5wuZlGKXq2x0LzprvtWWMplG0bFjE7ws9d2eaQ5/U\r
+ saAHAUQz/n8r/V4zfAgUQr8zhGMoY7G5En2N85HiZPCS74QwjAVumUm2BGZ6n/7WBU8v\r
+ td46augJSXNfYTyzGkeNJJ+EMuVJzSlWMA53UW1WRGmyK7ib3+H67UmcdFFwg75JjUOX\r
+ eUfawimie2yfQv+zZ94FIxtibcAd9XDgUyMOfj+AUUk+RoPH0lDuaxtOODbrKYj6xpYL\r
+ lcbux1EzYGWyB+4uHIebwAJKphhmy32sAMqOvFletRabdR7LZeXooeUeu0TmgVaUCcRe\r
+ Omyw==\r
+Received: by 10.180.97.35 with SMTP id dx3mr7003456wib.14.1349812157102;\r
+ Tue, 09 Oct 2012 12:49:17 -0700 (PDT)\r
+Received: from localhost (188-194-252-80-dynip.superkabel.de.\r
+ [188.194.252.80]) by mx.google.com with ESMTPS id\r
+ dm3sm29786895wib.3.2012.10.09.12.49.15 (version=TLSv1/SSLv3 cipher=OTHER);\r
+ Tue, 09 Oct 2012 12:49:15 -0700 (PDT)\r
+From: Stefan Hajnoczi <stefanha@gmail.com>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] notmuch-mutt: add --whole-thread flag\r
+Date: Tue, 9 Oct 2012 21:48:26 +0200\r
+Message-Id: <1349812106-26916-1-git-send-email-stefanha@gmail.com>\r
+X-Mailer: git-send-email 1.7.11.4\r
+X-Mailman-Approved-At: Tue, 09 Oct 2012 22:15:03 -0700\r
+Cc: Stefan Hajnoczi <stefanha@gmail.com>, Stefano Zacchiroli <zack@upsilon.cc>\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: Tue, 09 Oct 2012 19:49:20 -0000\r
+\r
+It can be useful to manipulate tags on an entire thread instead of just\r
+a single message. For example:\r
+\r
+ # Mark entire thread unread\r
+ notmuch-mutt tag --whole-thread -- -unread < MAIL\r
+\r
+Add the --whole-thread flag which first looks up the thread for a given\r
+message and then applies the tag action on the entire thread.\r
+\r
+Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>\r
+---\r
+Warning: I don't really know Perl :)\r
+\r
+It would be nice if notmuch's query syntax could match threads. Then\r
+core notmuch CLI could perform this operation in a single command:\r
+\r
+ # Mark entire thread unread given a single Message-ID\r
+ notmuch tag thread-contains(id:1234@foo.com) -- -unread\r
+\r
+Since the core cannot do this query today this patch bolts it on top for\r
+"notmuch-mutt tag".\r
+\r
+ contrib/notmuch-mutt/notmuch-mutt | 38 +++++++++++++++++++++++++++-----------\r
+ 1 file changed, 27 insertions(+), 11 deletions(-)\r
+\r
+diff --git a/contrib/notmuch-mutt/notmuch-mutt b/contrib/notmuch-mutt/notmuch-mutt\r
+index d14709d..8529940 100755\r
+--- a/contrib/notmuch-mutt/notmuch-mutt\r
++++ b/contrib/notmuch-mutt/notmuch-mutt\r
+@@ -125,6 +125,14 @@ sub get_message_id() {\r
+ return $1;\r
+ }\r
+ \r
++sub get_thread_id($) {\r
++ my ($mid) = @_;\r
++ my $search_cmd = 'notmuch search --output=threads '\r
++ . shell_quote("id:$mid");\r
++ `$search_cmd` =~ /^thread:(.*)$/;\r
++ return $1;\r
++}\r
++\r
+ sub search_action($$$@) {\r
+ my ($interactive, $results_dir, $remove_dups, @params) = @_;\r
+ \r
+@@ -141,20 +149,26 @@ sub search_action($$$@) {\r
+ sub thread_action($$@) {\r
+ my ($results_dir, $remove_dups, @params) = @_;\r
+ \r
+- my $mid = get_message_id();\r
+- my $search_cmd = 'notmuch search --output=threads ' . shell_quote("id:$mid");\r
+- my $tid = `$search_cmd`; # get thread id\r
+- chomp($tid);\r
++ my $tid = get_thread_id(get_message_id());\r
+ \r
+- search($results_dir, $remove_dups, $tid);\r
++ search($results_dir, $remove_dups, "thread:$tid");\r
+ }\r
+ \r
+-sub tag_action(@) {\r
++sub tag_action($@) {\r
++ my ($whole_thread, @params) = @_;\r
+ my $mid = get_message_id();\r
+ \r
+- system("notmuch tag "\r
+- . shell_quote(join(' ', @_))\r
+- . " id:$mid");\r
++ if ($whole_thread) {\r
++ my $tid = get_thread_id($mid);\r
++\r
++ system("notmuch tag "\r
++ . shell_quote(join(' ', @params))\r
++ . " thread:$tid");\r
++ } else {\r
++ system("notmuch tag "\r
++ . shell_quote(join(' ', @params))\r
++ . " id:$mid");\r
++ }\r
+ }\r
+ \r
+ sub die_usage() {\r
+@@ -170,12 +184,14 @@ sub main() {\r
+ my $interactive = 0;\r
+ my $help_needed = 0;\r
+ my $remove_dups = 0;\r
++ my $whole_thread = 0;\r
+ \r
+ my $getopt = GetOptions(\r
+ "h|help" => \$help_needed,\r
+ "o|output-dir=s" => \$results_dir,\r
+ "p|prompt" => \$interactive,\r
+- "r|remove-dups" => \$remove_dups);\r
++ "r|remove-dups" => \$remove_dups,\r
++ "w|whole-thread" => \$whole_thread);\r
+ if (! $getopt || $#ARGV < 0) { die_usage() };\r
+ my ($action, @params) = ($ARGV[0], @ARGV[1..$#ARGV]);\r
+ \r
+@@ -193,7 +209,7 @@ sub main() {\r
+ } elsif ($action eq "thread") {\r
+ thread_action($results_dir, $remove_dups, @params);\r
+ } elsif ($action eq "tag") {\r
+- tag_action(@params);\r
++ tag_action($whole_thread, @params);\r
+ } else {\r
+ die_usage();\r
+ }\r
+-- \r
+1.7.11.4\r
+\r