Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id CF0836DE1A3A for ; Fri, 1 Jan 2016 22:09:56 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" X-Spam-Flag: NO X-Spam-Score: 0.042 X-Spam-Level: X-Spam-Status: No, score=0.042 tagged_above=-999 required=5 tests=[AWL=0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jLmU1MdYz0ty for ; Fri, 1 Jan 2016 22:09:53 -0800 (PST) Received: from resqmta-po-06v.sys.comcast.net (resqmta-po-06v.sys.comcast.net [96.114.154.165]) by arlo.cworth.org (Postfix) with ESMTPS id 596366DE1830 for ; Fri, 1 Jan 2016 22:09:48 -0800 (PST) Received: from resomta-po-11v.sys.comcast.net ([96.114.154.235]) by resqmta-po-06v.sys.comcast.net with comcast id 0u9U1s00254zqzk01u9mMQ; Sat, 02 Jan 2016 06:09:46 +0000 Received: from mail.tremily.us ([73.221.72.168]) by resomta-po-11v.sys.comcast.net with comcast id 0u7k1s0033dr3C901u7kfW; Sat, 02 Jan 2016 06:07:45 +0000 Received: from ullr.tremily.us (unknown [192.168.10.7]) by mail.tremily.us (Postfix) with ESMTPS id E35841B2F577; Fri, 1 Jan 2016 22:07:43 -0800 (PST) Received: (nullmailer pid 15115 invoked by uid 1000); Sat, 02 Jan 2016 06:07:51 -0000 From: "W. Trevor King" To: notmuch@notmuchmail.org Cc: David Bremner , Tomi Ollila , Jani Nikula , Carl Worth , "W. Trevor King" Subject: [PATCH v2 3/4] nmbug-status: Wrap query phrases in parentheses when and-ing together Date: Fri, 1 Jan 2016 22:07:42 -0800 Message-Id: X-Mailer: git-send-email 2.1.0.60.g85f0837 In-Reply-To: References: In-Reply-To: References: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=comcast.net; s=q20140121; t=1451714986; bh=EsWtt64FdfG0VjYB6cAEuXizbJYNPg+zTVeSeV5aqjs=; h=Received:Received:Received:Received:From:To:Subject:Date: Message-Id; b=rmnOAFJyO9Hk2kN1jKsE0gN1r9Y6oJstHlAC4M1oI1uF1uNCCw2jJqhKU6IAOL1j5 5QErpH5NffRQa4pL0T9MwF1NBHBncy0Vrxd5i5cZtrg4BvoWZqpyKMahGjjxutEgY0 MX8b/puiTVMQvjMtl/xewAoqnJJtgyf+6orhmuKTvuqo3YD1JhwHf7uE/J4y5dVq8q WNcJSlbHfRXzpmqkG+TP4ugQzm2k2d+aBQmnNAX4mpenXSi/An0J3/71ZSGuUG8guQ kiBQsqHUiRXLaeSI/L3Rd/GdJ2oEzbiSJL8UK9TB8Y3bJdC9DFBs09K/HjoSlhLRGy LZaeqZFnRUKxQ== X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Jan 2016 06:09:57 -0000 For example: "query": ["tag:a", "tag:b or tag:c"] is now converted to: ( tag:a ) and ( tag:b or tag:c ) instead of the old: tag:a and tag:b or tag:c This helps us avoid confusion due to Xapian's higher-precedence AND [1], where the old query would be interpreted as: ( tag:a and tag:b ) or tag:c [1]: http://xapian.org/docs/queryparser.html --- NEWS | 3 +++ devel/nmbug/nmbug-status | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 9f2e860..403a046 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,9 @@ Notmuch 0.22 (UNRELEASED) nmbug-status ------------ +`nmbug-status` now wraps query phrases in parentheses when and-ing +them together, to avoid confusion about clause grouping. + `nmbug-status` now supports `meta.message-url` to override the Gmane template. For example, you can use: diff --git a/devel/nmbug/nmbug-status b/devel/nmbug/nmbug-status index d72f1db..7d3a76e 100755 --- a/devel/nmbug/nmbug-status +++ b/devel/nmbug/nmbug-status @@ -167,7 +167,8 @@ class Page (object): view['title'], sort_key)) if 'query-string' not in view: query = view['query'] - view['query-string'] = ' and '.join(query) + view['query-string'] = ' and '.join( + '( {} )'.format(q) for q in query) q = notmuch.Query(database, view['query-string']) q.set_sort(sort) threads = self._get_threads(messages=q.search_messages()) @@ -411,7 +412,7 @@ if args.list_views: elif args.get_query != None: for view in config['views']: if args.get_query == view['title']: - print(' and '.join(view['query'])) + print(' and '.join('( {} )'.format(q) for q in view['query'])) sys.exit(0) else: # only import notmuch if needed -- 2.1.0.60.g85f0837