[PATCH v2 4/7] emacs: Use result text properties for search result iteration

Austin Clements amdragon at MIT.EDU
Fri Jul 13 20:43:23 PDT 2012


This simplifies the traversal of regions of results and eliminates the
need for save-excursions (which tend to get in the way of maintaining
point when we make changes to the buffer).  It also fixes some strange
corner cases in the old line-based code where results that bordered
the region but were not included in it could be affected by region
commands.  Coincidentally, this also essentially enables multi-line
search result formats; the only remaining non-multi-line-capable
functions are notmuch-search-{next,previous}-thread, which are only
used interactively.
---
 emacs/notmuch.el |   61 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 8e1a769..92ba2c1 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -427,17 +427,33 @@ 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)
+	   , at body)
+	 (setq ,pos-sym (notmuch-search-result-end ,pos-sym)
+	       ,first-sym nil)))))
+
 (defun notmuch-search-properties-in-region (property beg end)
-  (save-excursion
-    (let ((output nil)
-	  (last-line (line-number-at-pos end))
-	  (max-line (- (line-number-at-pos (point-max)) 2)))
-      (goto-char beg)
-      (beginning-of-line)
-      (while (<= (line-number-at-pos) (min last-line max-line))
-	(setq output (cons (get-text-property (point) property) output))
-	(forward-line 1))
-      output)))
+  (let (output)
+    (notmuch-search-do-results beg end pos
+      (push (get-text-property pos property) output))
+    output))
 
 (defun notmuch-search-find-thread-id ()
   "Return the thread for the current thread"
@@ -517,28 +533,19 @@ and will also appear in a buffer named \"*Notmuch errors*\"."
   (plist-get (notmuch-search-get-result pos) :tags))
 
 (defun notmuch-search-get-tags-region (beg end)
-  (save-excursion
-    (let ((output nil)
-	  (last-line (line-number-at-pos end))
-	  (max-line (- (line-number-at-pos (point-max)) 2)))
-      (goto-char beg)
-      (while (<= (line-number-at-pos) (min last-line max-line))
-	(setq output (append output (notmuch-search-get-tags)))
-	(forward-line 1))
-      output)))
+  (let (output)
+    (notmuch-search-do-results beg end 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))
-    (save-excursion
-      (let ((last-line (line-number-at-pos end))
-	    (max-line (- (line-number-at-pos (point-max)) 2)))
-	(goto-char beg)
-	(while (<= (line-number-at-pos) (min last-line max-line))
-	  (notmuch-search-set-tags
-	   (notmuch-update-tags (notmuch-search-get-tags) tag-changes))
-	  (forward-line))))))
+    (notmuch-search-do-results beg end 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.
-- 
1.7.10



More information about the notmuch mailing list