From: Austin Clements Date: Sat, 14 Jul 2012 23:02:12 +0000 (+2000) Subject: [PATCH v3 0/8] emacs: JSON-based search cleanups X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=1783f0525f190f6e1946307d44f7145c94d0a6e2;p=notmuch-archives.git [PATCH v3 0/8] emacs: JSON-based search cleanups --- diff --git a/7a/9481f36c78f4258b9fed70fa6bbc07091ff36b b/7a/9481f36c78f4258b9fed70fa6bbc07091ff36b new file mode 100644 index 000000000..245420003 --- /dev/null +++ b/7a/9481f36c78f4258b9fed70fa6bbc07091ff36b @@ -0,0 +1,218 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by olra.theworths.org (Postfix) with ESMTP id 3B0D0431FBD + for ; Sat, 14 Jul 2012 16:02:28 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: -0.7 +X-Spam-Level: +X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 + tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled +Received: from olra.theworths.org ([127.0.0.1]) + by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id VLW9yq+XE6wt for ; + Sat, 14 Jul 2012 16:02:27 -0700 (PDT) +Received: from dmz-mailsec-scanner-6.mit.edu (DMZ-MAILSEC-SCANNER-6.MIT.EDU + [18.7.68.35]) + by olra.theworths.org (Postfix) with ESMTP id 9F019431FBC + for ; Sat, 14 Jul 2012 16:02:26 -0700 (PDT) +X-AuditID: 12074423-b7f396d0000008f4-d7-5001fa82b116 +Received: from mailhub-auth-1.mit.edu ( [18.9.21.35]) + by dmz-mailsec-scanner-6.mit.edu (Symantec Messaging Gateway) with SMTP + id 85.26.02292.28AF1005; Sat, 14 Jul 2012 19:02:26 -0400 (EDT) +Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) + by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id q6EN2PjU015442; + Sat, 14 Jul 2012 19:02:25 -0400 +Received: from drake.dyndns.org + (209-6-116-242.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com + [209.6.116.242]) (authenticated bits=0) + (User authenticated as amdragon@ATHENA.MIT.EDU) + by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q6EN2NrC008492 + (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); + Sat, 14 Jul 2012 19:02:24 -0400 (EDT) +Received: from amthrax by drake.dyndns.org with local (Exim 4.77) + (envelope-from ) + id 1SqBLz-0002G1-Md; Sat, 14 Jul 2012 19:02:23 -0400 +From: Austin Clements +To: notmuch@notmuchmail.org +Subject: [PATCH v3 0/8] emacs: JSON-based search cleanups +Date: Sat, 14 Jul 2012 19:02:12 -0400 +Message-Id: <1342306940-7499-1-git-send-email-amdragon@mit.edu> +X-Mailer: git-send-email 1.7.10 +In-Reply-To: <1342140319-19859-1-git-send-email-amdragon@mit.edu> +References: <1342140319-19859-1-git-send-email-amdragon@mit.edu> +X-Brightmail-Tracker: + H4sIAAAAAAAAA+NgFjrCIsWRmVeSWpSXmKPExsUixCmqrNv0izHA4MoOFos9+7wsVs/lsbh+ + cyazA7PH3dNcHjtn3WX3eLbqFnMAcxSXTUpqTmZZapG+XQJXxq+Tn1gL+vUqmne0sTYwvlLp + YuTkkBAwkfi+4xgThC0mceHeerYuRi4OIYF9jBL/pjxih3A2MEpsnXKcEaRKSOARk8SP2fIQ + ibmMEg9v7mIDSbAJaEhs278crEhEQFpi593ZrCA2s4ClxPfWe2BxYSD73vQ/YOtYBFQlNm/t + ZQaxeQXsJTpOH2GGOENe4un9PrCZnAKOEhu+XGCFWOwg0XhsJvMERv4FjAyrGGVTcqt0cxMz + c4pTk3WLkxPz8lKLdM30cjNL9FJTSjcxggKL3UV5B+Ofg0qHGAU4GJV4eJP8GQKEWBPLiitz + DzFKcjApifK+/skYIMSXlJ9SmZFYnBFfVJqTWnyIUYKDWUmEV+IrUI43JbGyKrUoHyYlzcGi + JM57LeWmv5BAemJJanZqakFqEUxWhoNDSYL3FchQwaLU9NSKtMycEoQ0EwcnyHAeoOEnQWp4 + iwsSc4sz0yHypxgVpcQhEgIgiYzSPLheWOS/YhQHekWY9yFIFQ8wacB1vwIazAQ0eNbPf/5A + g0sSEVJSDYy8DF9dnI68Zzsh80js2AK99fUv/RuUs+8XLYxZeGJeYdKl/y5n06NnVGYzKJ++ + w7/2ngnfnGoLQ+NZhvw3Fz54WLN4OzvjPolpoXa5oknJzr/+WFrJzG9at1SO2ZF3y8Q/kxZO + ODs368Hlr96hmteTfkaETO6+159+XcPfg5Etyqg43eB0+HclluKMREMt5qLiRADK7bRy1wIA AA== +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.13 +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, 14 Jul 2012 23:02:28 -0000 + +This version swaps out the notmuch-search-do-results macro for a +higher-order function, notmuch-search-foreach-result. This requires +less squiting to understand and clearly distinguishes the arguments +passed in to the function from the arguments passed to the callback. +This version also updates the docstring for +notmuch-search-result-format to mention that multi-line result formats +work and how to enter them, and it adds a NEWS patch. + +Diff from v2: + +diff --git a/NEWS b/NEWS +index a1a6e93..7b33f0d 100644 +--- a/NEWS ++++ b/NEWS +@@ -17,6 +17,20 @@ Maildir tag synchronization + Emacs Interface + --------------- + ++Search results now get re-colored when tags are updated ++ ++The formatting of tags in search results can now be customized ++ ++ Previously, attempting to change the format of tags in ++ `notmuch-search-result-format` would usually break tagging from ++ search-mode. We no longer make assumptions about the format. ++ ++Multi-line search result formats are now supported ++ ++ It is now possible to embed newlines in ++ `notmuch-search-result-format` to make individual search results ++ span multiple lines. ++ + Search now uses the JSON format internally + + This should address problems with unusual characters in authors and +diff --git a/emacs/notmuch.el b/emacs/notmuch.el +index 7302fa7..ec760dc 100644 +--- a/emacs/notmuch.el ++++ b/emacs/notmuch.el +@@ -69,7 +69,13 @@ + date, count, authors, subject, tags + For example: + (setq notmuch-search-result-format \(\(\"authors\" . \"%-40s\"\) +- \(\"subject\" . \"%s\"\)\)\)" ++ \(\"subject\" . \"%s\"\)\)\) ++Line breaks are permitted in format strings. Note that a line ++break at the end of an \"authors\" field will get elided if the ++authors list is long; place it instead at the beginning of the ++following field. To enter a line break when setting this ++variable with setq, use \\n. To enter a line break in customize, ++press \\[quoted-insert] C-j." + :type '(alist :key-type (string) :value-type (string)) + :group 'notmuch-search) + +@@ -433,32 +439,39 @@ returns nil" + (next-single-property-change (or pos (point)) 'notmuch-search-result + nil (point-max)))) + +-(defmacro notmuch-search-do-results (beg end pos-sym &rest body) +- "Invoke BODY for each result between BEG and END. +- +-POS-SYM will be bound to the point at the beginning of the +-current result." +- (declare (indent 3)) +- (let ((end-sym (make-symbol "end")) +- (first-sym (make-symbol "first"))) +- `(let ((,pos-sym (notmuch-search-result-beginning ,beg)) +- ;; End must be a marker in case body changes the text +- (,end-sym (copy-marker ,end)) +- ;; Make sure we examine one result, even if (= beg end) +- (,first-sym t)) +- ;; We have to be careful if the region extends beyond the +- ;; results. In this case, pos could be null or there could be +- ;; no result at pos. +- (while (and ,pos-sym (or (< ,pos-sym ,end-sym) ,first-sym)) +- (when (notmuch-search-get-result ,pos-sym) +- ,@body) +- (setq ,pos-sym (notmuch-search-result-end ,pos-sym) +- ,first-sym nil))))) ++(defun notmuch-search-foreach-result (beg end function) ++ "Invoke FUNCTION for each result between BEG and END. ++ ++FUNCTION should take one argument. It will be applied to the ++character position of the beginning of each result that overlaps ++the region between points BEG and END. As a special case, if (= ++BEG END), FUNCTION will be applied to the result containing point ++BEG." ++ ++ (lexical-let ((pos (notmuch-search-result-beginning beg)) ++ ;; End must be a marker in case function changes the ++ ;; text. ++ (end (copy-marker end)) ++ ;; Make sure we examine at least one result, even if ++ ;; (= beg end). ++ (first t)) ++ ;; We have to be careful if the region extends beyond the results. ++ ;; In this case, pos could be null or there could be no result at ++ ;; pos. ++ (while (and pos (or (< pos end) first)) ++ (when (notmuch-search-get-result pos) ++ (funcall function pos)) ++ (setq pos (notmuch-search-result-end pos) ++ first nil)))) ++;; Unindent the function argument of notmuch-search-foreach-result so ++;; the indentation of callers doesn't get out of hand. ++(put 'notmuch-search-foreach-result 'lisp-indent-function 2) + + (defun notmuch-search-properties-in-region (property beg end) + (let (output) +- (notmuch-search-do-results beg end pos +- (push (plist-get (notmuch-search-get-result pos) property) output)) ++ (notmuch-search-foreach-result beg end ++ (lambda (pos) ++ (push (plist-get (notmuch-search-get-result pos) property) output))) + output)) + + (defun notmuch-search-find-thread-id () +@@ -542,18 +555,20 @@ and will also appear in a buffer named \"*Notmuch errors*\"." + + (defun notmuch-search-get-tags-region (beg end) + (let (output) +- (notmuch-search-do-results beg end pos +- (setq output (append output (notmuch-search-get-tags pos)))) ++ (notmuch-search-foreach-result beg end ++ (lambda (pos) ++ (setq output (append output (notmuch-search-get-tags pos))))) + output)) + + (defun notmuch-search-tag-region (beg end &optional tag-changes) + "Change tags for threads in the given region." + (let ((search-string (notmuch-search-find-thread-id-region-search beg end))) + (setq tag-changes (funcall 'notmuch-tag search-string tag-changes)) +- (notmuch-search-do-results beg end pos +- (notmuch-search-set-tags +- (notmuch-update-tags (notmuch-search-get-tags pos) tag-changes) +- pos)))) ++ (notmuch-search-foreach-result beg end ++ (lambda (pos) ++ (notmuch-search-set-tags ++ (notmuch-update-tags (notmuch-search-get-tags pos) tag-changes) ++ pos))))) + + (defun notmuch-search-tag (&optional tag-changes) + "Change tags for the currently selected thread or region. + +