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

2012-07-14 Thread Jameson Graef Rollins
On Fri, Jul 13 2012, Austin Clements amdra...@mit.edu wrote:
 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.

So I tried to experiment with multi-line search results with this patch
series, but it didn't work.  I tried adding a '\n' in one of the
formatter fields, but I got a series of errors for each result insertion
in the buffer.  What's the way to get multi-line to work?

 +(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!

jamie.


pgpir2LGeaLnI.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


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

2012-07-14 Thread Austin Clements
Quoth Jameson Graef Rollins on Jul 14 at 12:31 pm:
 On Fri, Jul 13 2012, Austin Clements amdra...@mit.edu wrote:
  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.
 
 So I tried to experiment with multi-line search results with this patch
 series, but it didn't work.  I tried adding a '\n' in one of the
 formatter fields, but I got a series of errors for each result insertion
 in the buffer.  What's the way to get multi-line to work?

That's strange.  What was the error?

I've been testing with
   ((date . %12s )
(count . %-7s )
(authors . %-20s )
(subject . \n%s )
(tags . (%s)))
But maybe there are other cases it doesn't handle correctly?

  +(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.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


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

2012-07-14 Thread Austin Clements
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 amdra...@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))

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


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

2012-07-14 Thread Jameson Graef Rollins
On Sat, Jul 14 2012, Austin Clements amdra...@mit.edu wrote:
 That's strange.  What was the error?

 I've been testing with
((date . %12s )
 (count . %-7s )
 (authors . %-20s )
 (subject . \n%s )
 (tags . (%s)))
 But maybe there are other cases it doesn't handle correctly?

Hrm.  The error was:

  error in process filter: wrong type argument: wholenump, -13

However, that's in my test emacs setup.  It works fine in my normal
emacs session.  Lets assume this is just a problem with my setup that
I'll look into.

The other problem I seem to be running into is that the
customize-variable interface definitely doesn't handle newlines very
well.  If I try to add a '\n' in the interface it gets escaped, so I end
up with:

 (subject . \\n%s )

If I add the '\n' manually in my config, notmuch-search then interprets
the string correctly and adds newlines to the search results, but then
the customize-variable interface interprets the newline and adds a
newline the string field that kind makes the interface a little weird.
Is there proper way to add a newline to a string value in the
customize-variable interface that I'm not aware of?

In any event, this is in no way a blocker for this patch series.  This
is all totally tangential.  The patch series is great.

jamie.


pgppV4gW3Tw9i.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


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

2012-07-14 Thread Mark Walters

On Sat, 14 Jul 2012, Austin Clements amdra...@mit.edu wrote:
 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.

Having understood how macros work (thanks to Austin's patient
explanations on irc) this looks fine. So +1 for the whole series.

Best wishes

Mark
 ---
  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)
 +,@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
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


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

2012-07-14 Thread Austin Clements
Quoth Jameson Graef Rollins on Jul 14 at  2:13 pm:
 On Sat, Jul 14 2012, Austin Clements amdra...@mit.edu wrote:
  That's strange.  What was the error?
 
  I've been testing with
 ((date . %12s )
  (count . %-7s )
  (authors . %-20s )
  (subject . \n%s )
  (tags . (%s)))
  But maybe there are other cases it doesn't handle correctly?
 
 Hrm.  The error was:
 
   error in process filter: wrong type argument: wholenump, -13
 
 However, that's in my test emacs setup.  It works fine in my normal
 emacs session.  Lets assume this is just a problem with my setup that
 I'll look into.

Interesting.  The error in process filter suggests that it is
happening somewhere in the notmuch code under the search process
filter, so it's probably some combination of something unusual in your
environment and this patch.  If you M-x toggle-debug-on-error, will it
drop you into the debugger when this happens?

 The other problem I seem to be running into is that the
 customize-variable interface definitely doesn't handle newlines very
 well.  If I try to add a '\n' in the interface it gets escaped, so I end
 up with:
 
  (subject . \\n%s )
 
 If I add the '\n' manually in my config, notmuch-search then interprets
 the string correctly and adds newlines to the search results, but then
 the customize-variable interface interprets the newline and adds a
 newline the string field that kind makes the interface a little weird.
 Is there proper way to add a newline to a string value in the
 customize-variable interface that I'm not aware of?

I think this is just a sharp corner in customize and there's notmuch
we can do about it.  I believe the proper way to enter the newline
directly in customize is to hit C-q C-j (same way you get a raw
newline in any other buffer).  Given that I wouldn't expect anyone to
guess that, though, we could mention this in the defcustom's
docstring.

 In any event, this is in no way a blocker for this patch series.  This
 is all totally tangential.  The patch series is great.
 
 jamie.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


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

2012-07-14 Thread Jameson Graef Rollins
On Sat, Jul 14 2012, Austin Clements amdra...@mit.edu wrote:
 I think this is just a sharp corner in customize and there's notmuch
 we can do about it.  I believe the proper way to enter the newline
 directly in customize is to hit C-q C-j (same way you get a raw
 newline in any other buffer).  Given that I wouldn't expect anyone to
 guess that, though, we could mention this in the defcustom's
 docstring.

Ah.  C-q C-j definitely does it.  Thanks, Austin.

I'll follow up with a patch that modifies the doc string, which can
maybe help make things clearer for the uninitiated.

jamie.


pgpdSD0CDV8AE.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch