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@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) > > > + ,@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))