[PATCH v2 4/7] emacs: Use result text properties for search result iteration
Austin Clements
amdragon at MIT.EDU
Sat Jul 14 13:01:58 PDT 2012
Quoth myself on Jul 14 at 3:50 pm:
> Quoth Jameson Graef Rollins on Jul 14 at 12:31 pm:
> > On Fri, Jul 13 2012, Austin Clements <amdragon at MIT.EDU> wrote:
> > > +(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)))))
> >
> > Austin, can you explain why you use a defmacro here? I'm honestly have
> > a hard time parsing what's going on here. I understand in principle how
> > elisp macros work, but I don't see why it's needed here.
> >
> > I'm also trying to understand what the commas are doing
> > (e.g. ",pos-sym"). Are they doing some sort of escaping?
> >
> > Some sophisticated elisp here!
>
> I did this as a macro to parallel things like dolist and loop, I'll
> try this out with a higher-order procedure and see if the results are
> less opaque.
Here's what it looks like as a higher-order procedure and an example
use:
(defun notmuch-search-foreach-result (beg end function)
"Invoke FUNCTION with the position of each result between BEG and END."
(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)
(apply function pos))
(setq pos (notmuch-search-result-end pos)
first nil))))
(defun notmuch-search-properties-in-region (property beg end)
(let (output)
(notmuch-search-foreach-result
beg end
(lambda (pos)
(push (plist-get (notmuch-search-get-result pos) property) output)))
output))
More information about the notmuch
mailing list