Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 82 / 788ac96ea8512974fadbe32b7c440cf2088da5
1 Return-Path: <markwalters1009@gmail.com>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 1BBED431FAF\r
6         for <notmuch@notmuchmail.org>; Mon,  3 Jun 2013 13:53:14 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0.201\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0.201 tagged_above=-999 required=5\r
12         tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
13         FREEMAIL_ENVFROM_END_DIGIT=1, FREEMAIL_FROM=0.001,\r
14         RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
15 Received: from olra.theworths.org ([127.0.0.1])\r
16         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
17         with ESMTP id 6BRkwRF7Pc2F for <notmuch@notmuchmail.org>;\r
18         Mon,  3 Jun 2013 13:53:06 -0700 (PDT)\r
19 Received: from mail-we0-f176.google.com (mail-we0-f176.google.com\r
20         [74.125.82.176]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
21         (No client certificate requested)\r
22         by olra.theworths.org (Postfix) with ESMTPS id 68F0A431FAE\r
23         for <notmuch@notmuchmail.org>; Mon,  3 Jun 2013 13:53:06 -0700 (PDT)\r
24 Received: by mail-we0-f176.google.com with SMTP id t61so2118321wes.21\r
25         for <notmuch@notmuchmail.org>; Mon, 03 Jun 2013 13:53:05 -0700 (PDT)\r
26 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\r
27         h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;\r
28         bh=58UsGpDhPimdX29TjAueU5FMTRPqjKKUuniesk7SQAc=;\r
29         b=Z3YoZNVIjpAUlCOdbPxMGOa7yyW8HNXCpk279CZHnlPlqkQCp8sQ01N5ZSvwnhIzR+\r
30         /yfVHgn/RZxG9inDYJrzVLteF8ZF7UAGQcqsSCZFnoqGyDsDSTaGGRnZD6Yzz4EPIFHD\r
31         yjJWe7yXyNx7XtW6n26lteIQkf5iauyxsGcfUbKHZkBw4ZqRmP0I+slYhZr2zCmmVkZ8\r
32         E9H9B2nUB1bgX/U3isKdXceJ9iLwDIj7vcTpC8IQYIz3LBQhVRTrc7IlM3+14W2zgHnB\r
33         urRVjOY7Dp/xYAG+YeA2ilhTOlk8xxqh+WlQxuve2DOuykS6aO8eDHJcAMCkxJrBqMxJ\r
34         V/sQ==\r
35 X-Received: by 10.180.37.208 with SMTP id a16mr14714899wik.24.1370292783780;\r
36         Mon, 03 Jun 2013 13:53:03 -0700 (PDT)\r
37 Received: from localhost (93-97-24-31.zone5.bethere.co.uk. [93.97.24.31])\r
38         by mx.google.com with ESMTPSA id d10sm26144562wik.0.2013.06.03.13.53.02\r
39         for <multiple recipients>\r
40         (version=TLSv1.2 cipher=RC4-SHA bits=128/128);\r
41         Mon, 03 Jun 2013 13:53:03 -0700 (PDT)\r
42 From: Mark Walters <markwalters1009@gmail.com>\r
43 To: notmuch@notmuchmail.org,\r
44         jani@nikula.org\r
45 Subject: [PATCH v2] emacs: search: allow command line args as part of query\r
46 Date: Mon,  3 Jun 2013 21:52:56 +0100\r
47 Message-Id: <1370292776-24535-1-git-send-email-markwalters1009@gmail.com>\r
48 X-Mailer: git-send-email 1.7.9.1\r
49 In-Reply-To: <1370252526-18003-1-git-send-email-markwalters1009@gmail.com>\r
50 References: <1370252526-18003-1-git-send-email-markwalters1009@gmail.com>\r
51 X-BeenThere: notmuch@notmuchmail.org\r
52 X-Mailman-Version: 2.1.13\r
53 Precedence: list\r
54 List-Id: "Use and development of the notmuch mail system."\r
55         <notmuch.notmuchmail.org>\r
56 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
57         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
58 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
59 List-Post: <mailto:notmuch@notmuchmail.org>\r
60 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
61 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
62         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
63 X-List-Received-Date: Mon, 03 Jun 2013 20:53:14 -0000\r
64 \r
65 This allows command line arguments for notmuch-search to be part of\r
66 the query-string. The string must be of the form\r
67 [:blank:]*--cli-arguments -- query. I hope this doesn't clash with\r
68 xapian: I believe that queries shouldn't start with a "-".\r
69 \r
70 Correctly parsed example queries are\r
71 --sort=oldest-first -- tag:inbox\r
72 --exclude=false -- from:fred\r
73 \r
74 Some options (currently only sort-order) we parse in emacs, the rest\r
75 we just pass to the cli. In light testing it seems to work.\r
76 \r
77 A full custom parser would be nicer but at least here we are only parsing\r
78 the non-query part of a string which is relatively simple: indeed we\r
79 already do that in the c code.\r
80 \r
81 We could just implement the option for sort-order, but I thought for\r
82 interface consistency making all the options (sort-order exclude limit\r
83 and offset) work was worth the small extra hassle.\r
84 ---\r
85 This is a rather more complete version of the parent patch with a key\r
86 bugfix (thanks to Jani): saved searches with cli arguments work,\r
87 refreshing a query works correctly, filtering a query works correctly\r
88 (and can take extra cli arguments). \r
89 \r
90 It may all be too complex, and it may be too hackish but it does seem to work.\r
91 \r
92 Best wishes\r
93 \r
94 Mark\r
95 \r
96 \r
97 \r
98  emacs/notmuch-hello.el |    5 +++--\r
99  emacs/notmuch-lib.el   |   23 +++++++++++++++++++++++\r
100  emacs/notmuch.el       |   36 +++++++++++++++++++++++++-----------\r
101  3 files changed, 51 insertions(+), 13 deletions(-)\r
102 \r
103 diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el\r
104 index c1c6f4b..bcc1843 100644\r
105 --- a/emacs/notmuch-hello.el\r
106 +++ b/emacs/notmuch-hello.el\r
107 @@ -383,10 +383,11 @@ options will be handled as specified for\r
108  `notmuch-hello-insert-searches'."\r
109    (with-temp-buffer\r
110      (dolist (elem query-alist nil)\r
111 -      (let ((count-query (if (consp (cdr elem))\r
112 +      (let* ((full-count-query (if (consp (cdr elem))\r
113                              ;; do we have a different query for the message count?\r
114                              (third elem)\r
115 -                          (cdr elem))))\r
116 +                          (cdr elem)))\r
117 +            (count-query (car (notmuch-parse-query full-count-query))))\r
118         (insert\r
119          (notmuch-hello-filtered-query count-query\r
120                                        (or (plist-get options :filter-count)\r
121 diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el\r
122 index 28f78e0..705d4f3 100644\r
123 --- a/emacs/notmuch-lib.el\r
124 +++ b/emacs/notmuch-lib.el\r
125 @@ -189,6 +189,29 @@ user-friendly queries."\r
126    "Return a query that matches the message with id ID."\r
127    (concat "id:" (notmuch-escape-boolean-term id)))\r
128  \r
129 +(defun notmuch-search-parse-sort-order (args oldest-first)\r
130 +  (dolist (arg args nil)\r
131 +    (when (equal arg "--sort=oldest-first")\r
132 +      (setq oldest-first t))\r
133 +    (when (equal arg "--sort=newest-first")\r
134 +      (setq oldest-first nil)))\r
135 +  (setq args (delete "--sort=oldest-first" args))\r
136 +  (setq args (delete "--sort=newest-first" args))\r
137 +  (cons oldest-first args))\r
138 +\r
139 +(defun notmuch-parse-query (query)\r
140 +  "Parse a query into a search and cli arguments\r
141 +\r
142 +Returns a list consisting of query followed by the cli-args (as a\r
143 +list). If the string does not have cli-args then this will be nil."\r
144 +\r
145 +  (if (string-match "^[[:blank:]]*--.*? -- " query)\r
146 +      (let ((actual-query (substring query (match-end 0)))\r
147 +           (args (split-string (match-string 0 query) " " t)))\r
148 +       (message "Parsing query")\r
149 +       (cons actual-query args))\r
150 +    ;; no cli arguments\r
151 +    (list query)))\r
152  ;;\r
153  \r
154  (defun notmuch-common-do-stash (text)\r
155 diff --git a/emacs/notmuch.el b/emacs/notmuch.el\r
156 index 7994d74..6a4052e 100644\r
157 --- a/emacs/notmuch.el\r
158 +++ b/emacs/notmuch.el\r
159 @@ -255,6 +255,7 @@ For a mouse binding, return nil."\r
160    (notmuch-common-do-stash (notmuch-search-find-thread-id)))\r
161  \r
162  (defvar notmuch-search-query-string)\r
163 +(defvar notmuch-search-query-args)\r
164  (defvar notmuch-search-target-thread)\r
165  (defvar notmuch-search-target-line)\r
166  (defvar notmuch-search-continuation)\r
167 @@ -409,6 +410,7 @@ Complete list of currently available key bindings:\r
168    (interactive)\r
169    (kill-all-local-variables)\r
170    (make-local-variable 'notmuch-search-query-string)\r
171 +  (make-local-variable 'notmuch-search-query-args)\r
172    (make-local-variable 'notmuch-search-oldest-first)\r
173    (make-local-variable 'notmuch-search-target-thread)\r
174    (make-local-variable 'notmuch-search-target-line)\r
175 @@ -897,7 +899,7 @@ PROMPT is the string to prompt with."\r
176                               'notmuch-search-history nil nil)))))\r
177  \r
178  ;;;###autoload\r
179 -(defun notmuch-search (&optional query oldest-first target-thread target-line continuation)\r
180 +(defun notmuch-search (&optional query oldest-first target-thread target-line continuation cli-args)\r
181    "Run \"notmuch search\" with the given `query' and display results.\r
182  \r
183  If `query' is nil, it is read interactively from the minibuffer.\r
184 @@ -909,13 +911,20 @@ Other optional parameters are used as follows:\r
185    target-line: The line number to move to if the target thread does not\r
186                 appear in the search results."\r
187    (interactive)\r
188 -  (let* ((query (or query (notmuch-read-query "Notmuch search: ")))\r
189 +  (let* ((full-query (or query (notmuch-read-query "Notmuch search: ")))\r
190 +        (parsed-query (notmuch-parse-query full-query))\r
191 +        (query (car parsed-query))\r
192 +        (cli-args (or cli-args (cdr parsed-query)))\r
193 +        (combined-order-query (notmuch-search-parse-sort-order cli-args oldest-first))\r
194 +        (oldest-first (car combined-order-query))\r
195 +        (cli-args (cdr combined-order-query))\r
196          (buffer (get-buffer-create (notmuch-search-buffer-title query))))\r
197      (switch-to-buffer buffer)\r
198      (notmuch-search-mode)\r
199      ;; Don't track undo information for this buffer\r
200      (set 'buffer-undo-list t)\r
201      (set 'notmuch-search-query-string query)\r
202 +    (set 'notmuch-search-query-args cli-args)\r
203      (set 'notmuch-search-oldest-first oldest-first)\r
204      (set 'notmuch-search-target-thread target-thread)\r
205      (set 'notmuch-search-target-line target-line)\r
206 @@ -928,13 +937,13 @@ Other optional parameters are used as follows:\r
207        (erase-buffer)\r
208        (goto-char (point-min))\r
209        (save-excursion\r
210 -       (let ((proc (notmuch-start-notmuch\r
211 +       (let ((proc (apply #'notmuch-start-notmuch\r
212                      "notmuch-search" buffer #'notmuch-search-process-sentinel\r
213                      "search" "--format=sexp" "--format-version=1"\r
214 -                    (if oldest-first\r
215 +                    (if notmuch-search-oldest-first\r
216                          "--sort=oldest-first"\r
217                        "--sort=newest-first")\r
218 -                    query))\r
219 +                    (append cli-args (list query))))\r
220               ;; Use a scratch buffer to accumulate partial output.\r
221               ;; This buffer will be killed by the sentinel, which\r
222               ;; should be called no matter how the process dies.\r
223 @@ -957,9 +966,10 @@ same relative position within the new buffer."\r
224         (oldest-first notmuch-search-oldest-first)\r
225         (target-thread (notmuch-search-find-thread-id 'bare))\r
226         (query notmuch-search-query-string)\r
227 -       (continuation notmuch-search-continuation))\r
228 +       (continuation notmuch-search-continuation)\r
229 +       (cli-args notmuch-search-query-args))\r
230      (notmuch-kill-this-buffer)\r
231 -    (notmuch-search query oldest-first target-thread target-line continuation)\r
232 +    (notmuch-search query oldest-first target-thread target-line continuation cli-args)\r
233      (goto-char (point-min))))\r
234  \r
235  (defcustom notmuch-poll-script nil\r
236 @@ -1024,18 +1034,22 @@ search."\r
237    (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))\r
238    (notmuch-search-refresh-view))\r
239  \r
240 -(defun notmuch-search-filter (query)\r
241 +(defun notmuch-search-filter (full-query)\r
242    "Filter the current search results based on an additional query string.\r
243  \r
244  Runs a new search matching only messages that match both the\r
245  current search results AND the additional query string provided."\r
246    (interactive (list (notmuch-read-query "Filter search: ")))\r
247 -  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)\r
248 +  (let* ((parsed-query (notmuch-parse-query full-query))\r
249 +        (query (car parsed-query))\r
250 +        (grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query)\r
251                            (concat "( " query " )")\r
252 -                        query)))\r
253 +                        query))\r
254 +        (extra-cli-args (cdr parsed-query))\r
255 +        (cli-args (append notmuch-search-query-args extra-cli-args)))\r
256      (notmuch-search (if (string= notmuch-search-query-string "*")\r
257                         grouped-query\r
258 -                     (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first)))\r
259 +                     (concat notmuch-search-query-string " and " grouped-query)) notmuch-search-oldest-first nil nil nil cli-args)))\r
260  \r
261  (defun notmuch-search-filter-by-tag (tag)\r
262    "Filter the current search results based on a single tag.\r
263 -- \r
264 1.7.9.1\r
265 \r