[notmuch] [PATCH 5/5] Remove the global expand body keymapping

2009-11-23 Thread Alexander Botero-Lowry
---
 notmuch.el |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index af0c487..907df2c 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -61,7 +61,6 @@
 ; overlays-at to query and manipulate the current overlay.
 (define-key map "a" 'notmuch-show-archive-thread)
 (define-key map "A" 'notmuch-show-mark-read-then-archive-thread)
-(define-key map "b" 'notmuch-show-toggle-body-read-visible)
 (define-key map "m" 'message-mail)
 (define-key map "n" 'notmuch-show-next-message)
 (define-key map "N" 'notmuch-show-mark-read-then-next-open-message)
-- 
1.6.5.2



[notmuch] [PATCH 4/5] Make bodies locally toggleable

2009-11-23 Thread Alexander Botero-Lowry
Having actually implemented this, I realized that my
initial approach of providing a function to configure
a button was wrong. Instead I've replaced that with
button types. This then makes it possible to provide
the fully expanded view when all threads in a message
are unread.

It also has the potential to allow global-expansion functions
if that is desireable
---
 notmuch.el |   89 +++
 1 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 23a07cc..af0c487 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -497,12 +497,15 @@ which this thread was originally shown."
   (force-window-update)
   (redisplay t))

-(defun notmuch-configure-invisibility-button (btn invis-spec help-msg)
-  (button-put btn 'invisibility-spec invis-spec)
-  (button-put btn 'action 'notmuch-toggle-invisible-action)
-  (button-put btn 'follow-link t)
-  (button-put btn 'help-echo (concat "mouse-1, RET: " help-msg))
-)
+(define-button-type 'notmuch-button-invisibility-toggle-type 'action 
'notmuch-toggle-invisible-action 'follow-link t)
+(define-button-type 'notmuch-button-citation-toggle-type 'help-echo "mouse-1, 
RET: Show citation"
+  :supertype 'notmuch-button-invisibility-toggle-type)
+(define-button-type 'notmuch-button-signature-toggle-type 'help-echo "mouse-1, 
RET: Show signature"
+  :supertype 'notmuch-button-invisibility-toggle-type)
+(define-button-type 'notmuch-button-headers-toggle-type 'help-echo "mouse-1, 
RET: Show headers"
+  :supertype 'notmuch-button-invisibility-toggle-type)
+(define-button-type 'notmuch-button-body-toggle-type 'help-echo "mouse-1, RET: 
Show message"
+  :supertype 'notmuch-button-invisibility-toggle-type)

 (defun notmuch-show-markup-citations-region (beg end depth)
   (goto-char beg)
@@ -525,7 +528,9 @@ which this thread was originally shown."
  "-line citation.]")))
 (goto-char (- beg-sub 1))
 (insert (concat "\n" indent))
-(notmuch-configure-invisibility-button (insert-button 
cite-button-text) invis-spec "Show citation")
+(insert-button cite-button-text
+   'invisibility-spec invis-spec
+   :type 'notmuch-button-citation-toggle-type)
 (insert "\n")
 (goto-char (+ (length cite-button-text) p))
   
@@ -541,9 +546,11 @@ which this thread was originally shown."

 (goto-char (- beg-sub 1))
 (insert (concat "\n" indent))
-(notmuch-configure-invisibility-button
- (insert-button (concat "[" (number-to-string sig-lines)
-"-line signature.]"))  invis-spec 
"Show signature")
+(let ((sig-button-text (concat "[" (number-to-string 
sig-lines)
+   "-line signature.]")))
+  (insert-button sig-button-text 'invisibility-spec 
invis-spec
+ :type 
'notmuch-button-signature-toggle-type)
+ )
 (insert "\n")
 (goto-char end))
   (forward-line
@@ -572,16 +579,19 @@ which this thread was originally shown."
 (while (< (point) end)
   (notmuch-show-markup-part beg end depth

-(defun notmuch-show-markup-body (depth)
+(defun notmuch-show-markup-body (depth btn)
   (re-search-forward notmuch-show-body-begin-regexp)
   (forward-line)
   (let ((beg (point-marker)))
 (re-search-forward notmuch-show-body-end-regexp)
 (let ((end (copy-marker (match-beginning 0
   (notmuch-show-markup-parts-region beg end depth)
-  (if (not (notmuch-show-message-unread-p))
- (overlay-put (make-overlay beg end)
-  'invisible 'notmuch-show-body-read))
+  (let ((invis-spec (make-symbol "notmuch-show-body-read")))
+(overlay-put (make-overlay beg end)
+ 'invisible invis-spec)
+(button-put btn 'invisibility-spec invis-spec)
+(if (not (notmuch-show-message-unread-p))
+(add-to-invisibility-spec invis-spec)))
   (set-marker beg nil)
   (set-marker end nil)
   )))
@@ -589,10 +599,12 @@ which this thread was originally shown."
 (defun notmuch-show-markup-header (depth)
   (re-search-forward notmuch-show-header-begin-regexp)
   (forward-line)
-  (let ((beg (point-marker)))
+  (let ((beg (point-marker))
+(btn nil))
 (end-of-line)
 ; Inverse video for subject
 (overlay-put (make-overlay beg (point)) 'face '(:inverse-video t))
+(setq btn (make-button beg (point) :type 'notmuch-button-body-toggle-type))
 (forward-line 1)
 (end-of-line)
 (let ((beg-hidden (point-marker)))
@@ -614,23 +626,25 @@ which this thread was originally shown."
'invisible invis-spec)
   (goto-char 

[notmuch] [PATCH 3/5] make a nice function for generating invisibility toggle buttons

2009-11-23 Thread Alexander Botero-Lowry
I realized I was replicating this code over and over again, so this
way if I change my mind about something I only have to do it on one
place.
---
 notmuch.el |   45 -
 1 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index ed1f7cb..23a07cc 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -497,6 +497,13 @@ which this thread was originally shown."
   (force-window-update)
   (redisplay t))

+(defun notmuch-configure-invisibility-button (btn invis-spec help-msg)
+  (button-put btn 'invisibility-spec invis-spec)
+  (button-put btn 'action 'notmuch-toggle-invisible-action)
+  (button-put btn 'follow-link t)
+  (button-put btn 'help-echo (concat "mouse-1, RET: " help-msg))
+)
+
 (defun notmuch-show-markup-citations-region (beg end depth)
   (goto-char beg)
   (beginning-of-line)
@@ -512,22 +519,13 @@ which this thread was originally shown."
   (invis-spec (make-symbol "notmuch-citation-region")))
   (add-to-invisibility-spec invis-spec)
  (overlay-put overlay 'invisible invis-spec)
-  (let (
-(p (point))
+  (let ((p (point))
 (cite-button-text
  (concat "["  (number-to-string (count-lines beg-sub 
(point)))
- "-line citation.]"))
-)
+ "-line citation.]")))
 (goto-char (- beg-sub 1))
 (insert (concat "\n" indent))
-(let ((cite-button (insert-button cite-button-text)))
-  (button-put cite-button 'invisibility-spec invis-spec)
-  (button-put cite-button 'action 
'notmuch-toggle-invisible-action)
-  (button-put cite-button 'follow-link t)
-  (button-put cite-button 'help-echo
-  "mouse-1, RET: Show citation")
-
-  )
+(notmuch-configure-invisibility-button (insert-button 
cite-button-text) invis-spec "Show citation")
 (insert "\n")
 (goto-char (+ (length cite-button-text) p))
   
@@ -543,16 +541,9 @@ which this thread was originally shown."

 (goto-char (- beg-sub 1))
 (insert (concat "\n" indent))
-(let ((sig-button (insert-button 
-   (concat "[" (number-to-string sig-lines)
- "-line signature.]"
-  (button-put sig-button 'invisibility-spec invis-spec)
-  (button-put sig-button 'action
-  'notmuch-toggle-invisible-action)
-  (button-put sig-button 'follow-link t)
-  (button-put sig-button 'help-echo
-  "mouse-1, RET: Show signature")
-  )
+(notmuch-configure-invisibility-button
+ (insert-button (concat "[" (number-to-string sig-lines)
+"-line signature.]"))  invis-spec 
"Show signature")
 (insert "\n")
 (goto-char end))
   (forward-line
@@ -623,13 +614,9 @@ which this thread was originally shown."
'invisible invis-spec)
   (goto-char beg)
   (forward-line)
-  (let ((header-button (make-button (line-beginning-position) 
(line-end-position
-(button-put header-button 'invisibility-spec (cons invis-spec t))
-(button-put header-button 'action 'notmuch-toggle-invisible-action)
-(button-put header-button 'follow-link t)
-(button-put header-button 'help-echo
-"mouse-1, RET: Show headers")
-  ))
+  (notmuch-configure-invisibility-button
+   (make-button (line-beginning-position) (line-end-position))
+   (cons invis-spec t) "Show headers"))
 (goto-char end)
 (insert "\n")
(set-marker beg nil)
-- 
1.6.5.2



[notmuch] [PATCH 2/5] cleanup a lot of left-overs from the global invis

2009-11-23 Thread Alexander Botero-Lowry
---
 notmuch.el |   36 
 1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 8aee286..ed1f7cb 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -62,8 +62,6 @@
 (define-key map "a" 'notmuch-show-archive-thread)
 (define-key map "A" 'notmuch-show-mark-read-then-archive-thread)
 (define-key map "b" 'notmuch-show-toggle-body-read-visible)
-(define-key map "c" 'notmuch-show-toggle-citations-visible)
-(define-key map "h" 'notmuch-show-toggle-headers-visible)
 (define-key map "m" 'message-mail)
 (define-key map "n" 'notmuch-show-next-message)
 (define-key map "N" 'notmuch-show-mark-read-then-next-open-message)
@@ -72,7 +70,6 @@
 (define-key map (kbd "C-p") 'notmuch-show-previous-line)
 (define-key map "q" 'kill-this-buffer)
 (define-key map "r" 'notmuch-show-reply)
-(define-key map "s" 'notmuch-show-toggle-signatures-visible)
 (define-key map "v" 'notmuch-show-view-all-mime-parts)
 (define-key map "w" 'notmuch-show-view-raw-message)
 (define-key map "x" 'kill-this-buffer)
@@ -666,39 +663,6 @@ which this thread was originally shown."
   (notmuch-show-markup-message)))
   (notmuch-show-hide-markers))

-(defun notmuch-show-toggle-citations-visible ()
-  "Toggle visibility of citations"
-  (interactive)
-  (if notmuch-show-citations-visible
-  (add-to-invisibility-spec 'notmuch-show-citation)
-(remove-from-invisibility-spec 'notmuch-show-citation))
-  (set 'notmuch-show-citations-visible (not notmuch-show-citations-visible))
-  ; Need to force the redisplay for some reason
-  (force-window-update)
-  (redisplay t))
-
-(defun notmuch-show-toggle-signatures-visible ()
-  "Toggle visibility of signatures"
-  (interactive)
-  (if notmuch-show-signatures-visible
-  (add-to-invisibility-spec 'notmuch-show-signature)
-(remove-from-invisibility-spec 'notmuch-show-signature))
-  (set 'notmuch-show-signatures-visible (not notmuch-show-signatures-visible))
-  ; Need to force the redisplay for some reason
-  (force-window-update)
-  (redisplay t))
-
-(defun notmuch-show-toggle-headers-visible ()
-  "Toggle visibility of header fields"
-  (interactive)
-  (if notmuch-show-headers-visible
-  (add-to-invisibility-spec 'notmuch-show-header)
-(remove-from-invisibility-spec 'notmuch-show-header))
-  (set 'notmuch-show-headers-visible (not notmuch-show-headers-visible))
-  ; Need to force the redisplay for some reason
-  (force-window-update)
-  (redisplay t))
-
 (defun notmuch-show-toggle-body-read-visible ()
   "Toggle visibility of message bodies of read messages"
   (interactive)
-- 
1.6.5.2



[notmuch] [PATCH 1/5] make headers locally expandable/collapsable

2009-11-23 Thread Alexander Botero-Lowry
---
 notmuch.el |   18 +++---
 1 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index fa6e7de..8aee286 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -605,7 +605,8 @@ which this thread was originally shown."
 (end-of-line)
 ; Inverse video for subject
 (overlay-put (make-overlay beg (point)) 'face '(:inverse-video t))
-(forward-line 2)
+(forward-line 1)
+(end-of-line)
 (let ((beg-hidden (point-marker)))
   (re-search-forward notmuch-show-header-end-regexp)
   (beginning-of-line)
@@ -619,8 +620,19 @@ which this thread was originally shown."
   (forward-line)
   )
(indent-rigidly beg end depth)
-   (overlay-put (make-overlay beg-hidden end)
-'invisible 'notmuch-show-header)
+(let ((invis-spec (make-symbol "notmuch-show-header")))
+  (add-to-invisibility-spec (cons invis-spec t))
+  (overlay-put (make-overlay beg-hidden end)
+   'invisible invis-spec)
+  (goto-char beg)
+  (forward-line)
+  (let ((header-button (make-button (line-beginning-position) 
(line-end-position
+(button-put header-button 'invisibility-spec (cons invis-spec t))
+(button-put header-button 'action 'notmuch-toggle-invisible-action)
+(button-put header-button 'follow-link t)
+(button-put header-button 'help-echo
+"mouse-1, RET: Show headers")
+  ))
 (goto-char end)
 (insert "\n")
(set-marker beg nil)
-- 
1.6.5.2



[notmuch] Multithreaded access

2009-11-23 Thread Peter Wang
Hi,

I am also toying around with a curses frontend for notmuch :-)
One thing that I would really like to have is asynchronous search:
I should be able to begin reading mail even while search results
are rolling in.

At the moment I'm using one read-only database_t* and creating multiple
queries off it.  There's a background thread[1] slurping up  search
results at a time, then passes them to the main thread.  The main thread
also handles the pager.  When the user goes to open a thread, it creates
a separate query_t so that it can look up the messages and their headers
and filenames.

It seems to work, but sometimes crashes.  I'm wondering if there is
something inherently wrong with this design, so that I should try a
different approach.

A future concern is how to handle tag updates.  Could I open the database
for writing in one thread, and read-only in another?

Peter

[1] Actually, I am playing around with Go at the same time so they are
really goroutines.  Any problems could very well be related to this.


[notmuch] [PATCH] Stay out of tmp to respect the Maildir spec.

2009-11-23 Thread Jed Brown
---
 notmuch-new.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/notmuch-new.c b/notmuch-new.c
index 8172b49..e32b92a 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -159,6 +159,7 @@ add_files_recursive (notmuch_database_t *notmuch,
 * user specify files to be ignored. */
if (strcmp (entry->d_name, ".") == 0 ||
strcmp (entry->d_name, "..") == 0 ||
+   strcmp (entry->d_name, "tmp") == 0 ||
strcmp (entry->d_name, ".notmuch") ==0)
{
continue;
-- 
1.6.5.3



[notmuch] Notmuch doesn't index new mails when mail location contains symlinks

2009-11-23 Thread Mikhail Gusarov

Twas brillig at 16:03:00 23.11.2009 UTC+01 when jed at 59A2.org did gyre and 
gimble:

 JB> The real solution is for notmuch to check mtime of whatever the
 JB> symlink's target.

It does exactly this AFACT, stat() everywhere, not lstat().

-- 
  http://fossarchy.blogspot.com/
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/c670575f/attachment.pgp>


[notmuch] Notmuch doesn't index new mails when mail location contains symlinks

2009-11-23 Thread Mikhail Gusarov

Twas brillig at 16:01:41 23.11.2009 UTC+01 when tassilo at member.fsf.org did 
gyre and gimble:

 >>> Probably mail does not get indexed due to mtime checks. Please try
 >>> whether touch'ing directory with mailboxes makes it work.
 >> No, it seems that doesn't help either.
 TH> Ah, I'm stupid!  I don't have to touch the symlinks or the
 TH> directories inside the locations the symlinks point to, but instead
 TH> I have to touch the top-level directory where the symlinks are
 TH> contained in.  Then it works as expected, AFAICT.

Really odd.

-- 
  http://fossarchy.blogspot.com/
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/815c371f/attachment.pgp>


[notmuch] [PATCH] Support multiple configuration files via $NOTMUCH_CONFIG

2009-11-23 Thread Ingmar Vanhassel
Excerpts from Alec Berryman's message of Sun Nov 22 06:18:26 +0100 2009:
> If present, $NOTMUCH_CONFIG will be used as the configuration file
> location.

I'm a bit late to the party, but how about adding the more generic
NOTMUCH_OPTIONS, and --config-file, -c options to pass the path to the
configuration file?

-- 
Exherbo KDE, X.org maintainer


[notmuch] [PATCH] notmuch.el: Use variable notmuch-search-oldest-first to decide the search order

2009-11-23 Thread Aneesh Kumar K.V
Make sure we use notmuch-search-oldest-first to decide the how
the search result should be displayed. This helps to set the
value to nil and have latest mail shown first

Signed-off-by: Aneesh Kumar K.V 
---
 notmuch.el |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index af4ceec..5582132 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -840,7 +840,8 @@ thread from that buffer can be show when done with this 
one)."
 (fset 'notmuch-search-mode-map notmuch-search-mode-map)

 (defvar notmuch-search-query-string)
-(defvar notmuch-search-oldest-first)
+(defvar notmuch-search-oldest-first t
+  "Show the oldest mail first in the search-mode")

 (defun notmuch-search-scroll-up ()
   "Scroll up, moving point to last message in thread if at end."
@@ -1106,7 +1107,7 @@ current search results AND that are tagged with the given 
tag."
 (defun notmuch ()
   "Run notmuch to display all mail with tag of 'inbox'"
   (interactive)
-  (notmuch-search "tag:inbox" t))
+  (notmuch-search "tag:inbox" notmuch-search-oldest-first))

 (setq mail-user-agent 'message-user-agent)

@@ -1176,7 +1177,7 @@ results for the search terms in that line.
   (setq folder (notmuch-folder-find-name)))
   (let ((search (assoc folder notmuch-folders)))
 (if search
-   (notmuch-search (cdr search) t
+   (notmuch-search (cdr search) notmuch-search-oldest-first

 (defun notmuch-folder ()
   "Show the notmuch folder view and update the displayed counts."
-- 
1.6.5.2.74.g610f9



[notmuch] Notmuch doesn't index new mails when mail location contains symlinks

2009-11-23 Thread Mikhail Gusarov

Twas brillig at 14:55:40 23.11.2009 UTC+01 when tassilo at member.fsf.org did 
gyre and gimble:

 TH> Whenever I delete those symlinks and created them anew, the new
 TH> mails get indexed with the next "notmuch new".  Of course, I could
 TH> create a script that does exactly that, but there should be a
 TH> better way, right?

Probably mail does not get indexed due to mtime checks. Please try
whether touch'ing directory with mailboxes makes it work.

-- 
  http://fossarchy.blogspot.com/
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/45b239ce/attachment.pgp>


[notmuch] [PATCH] Make search filters handle disjunctive queries.

2009-11-23 Thread Jed Brown
On Mon, 23 Nov 2009 10:26:47 -0800, Keith Packard  wrote:

> Remember to split patches which do more than one thing into separate
> commits.

These are variants of the same operation, but I'll split in the future.

> > +  (let ((grouped-query (if (string-match-p 
> > notmuch-search-disjunctive-regexp query) (concat "( " query " )") query)))
> > +(notmuch-search (concat notmuch-search-query-string " and " 
> > grouped-query) notmuch-search-oldest-first)))
> 
> Is there some reason not to just always add the parens?

That's what I did initially, but it's messy to look at in the mode line
after applying successive filters.

> This seems useful; how does it deal with the tag completion stuff?

It doesn't do anything special, but I haven't been following that
carefully.  My thought was that eventually the regular interactive
search and filters, would have semantic completion, e.g. the user enters

  tag:ab

and tags would be completed, but they could also do

  from:long.unwieldy.addr

In filter-by-tag, the natural thing would be to only complete tags, the
user would be on their own to spell out AND, OR, and NOT.  Unfortunately
I'm not familiar enough with elisp to implement this quickly.

A closely related issue is managing the address book.  I guess the usual
advice is to use BBDB.  I don't know if it's better to hook into that or
for Notmuch to have it's own lightweight approach.  I could imagine
harvesting addresses of everyone I've sent mail to and giving me a
semi-automated way to merge addresses that are likely to point to the
same person.


Jed


[notmuch] notmuch 'index' mode.

2009-11-23 Thread Keith Packard
On Mon, 23 Nov 2009 19:16:54 -0800, Carl Worth  wrote:

> So what next for the user? We've got lots of empty space in the folder
> view, so I think what I'd like is to provide some suggestions on search
> strings to try, and then to make it obvious how to associate a name with
> a search string. And at that point, I'd like that name to be added to
> the folder view.

Right, associate a name for the search from the *search* view instead of
the folder view. Then it's just a matter of using that command and
typing a name. At that point, you get the new folder (or named search)
added to the main window. That's a great plan.

> Then tags become something that are just for manual manipulation. What
> do you think?

So you wouldn't generally end up using tags? And each time you wanted to
view a folder you'd really get a new search result? I can see some
benefits if you're using time-range based searches (show me all the mail


[notmuch] [PATCH] Make addresses case insensitive for the purpose of constructing replies.

2009-11-23 Thread Jed Brown
The domain is alway case insensitive, but in principle the username is
case sensitive.  Few systems actually enforce this so I think a good
default is to treat the entire address as case insensitive, it will
eliminate a lot of superfluous self-addressed messages and reply from
the correct address in these cases.

Signed-off-by: Jed Brown 
---
 notmuch-reply.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 44e1766..cd81e76 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -97,12 +97,12 @@ address_is_users (const char *address, notmuch_config_t 
*config)
 size_t i, other_len;

 primary = notmuch_config_get_user_primary_email (config);
-if (strcmp (primary, address) == 0)
+if (strcasecmp (primary, address) == 0)
return 1;

 other = notmuch_config_get_user_other_email (config, _len);
 for (i = 0; i < other_len; i++)
-   if (strcmp (other[i], address) == 0)
+   if (strcasecmp (other[i], address) == 0)
return 1;

 return 0;
-- 
1.6.5.3



[notmuch] notmuch 'index' mode.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 23:18:33 -0800, Keith Packard  wrote:
> On Mon, 23 Nov 2009 07:06:06 +0100, Carl Worth  wrote:
> > 
> >   * The mode documentation really needs to walk the user through how to
> > setup a custom set of folders.
> 
> You can use the standard emacs customization interface, although it's
> not exactly well documented there. Additional docs are clearly
> indicated.

Yes. I think that's a bit too hidden.

I'm imagining the case of a new user running notmuch. First, if we're
going to allow them to start off from inside emacs rather than the
command-line (and why not?) then I think we can pretty much just run
"notmuch setup" and "notmuch new" for the user (and those walk the user
through things well already.

Then, I'd like the user to be seeing the folder view right away (since
that's the primary view). We've got support for searching while still
indexing, so if we refresh occasionally, the user will be able to see
the inbox count just count up while indexing occurs.

So what next for the user? We've got lots of empty space in the folder
view, so I think what I'd like is to provide some suggestions on search
strings to try, and then to make it obvious how to associate a name with
a search string. And at that point, I'd like that name to be added to
the folder view.

And notice, I don't think we'll need to do the "virtual tag" thing of
associating a tag name with a search and doing the work of making
notmuch maintain the consistency of that tag and search string. It will
be much more clean (and shouldn't be any less fast) to just do the
searches for the original search terms, (rather than searching for tag
terms that were previously applied by searching for the search terms).

Then tags become something that are just for manual manipulation. What
do you think?

> >   * It's not opening my "to-me" folder for some reason. (I thought it
> > was the '-' at first, but "xorg-board" is working fine). I can debug
> > this later.
> 
> It shouldn't work on xorg-board either -- it just skips forward one
> 'word' and assumes it's gotten the folder name. Lame programming, I
> know. Should be easy to fix.

Ah, that's it. So "xorg-board" only looked like it worked because I had
a "xorg" folder as well. :-)

> What more do you need? Pretty fonts? Icons? A pony?

Heh. Just some guidance on what the user can do. It's nice that we have
room to do this, (since we don't on the search results view).

> Threads or messages? Threads are more expensive to compute, and when the
> number is zero, it means the same thing. But, it is surprising to see a
> huge number in the folder view and then get only a handful of threads in
> the search view. Perhaps if the count is small enough we can go through
> and actually figure out how many threads are involved.

Maybe something like that.

-Carl


[notmuch] [PATCH] Make search filters handle disjunctive queries.

2009-11-23 Thread Jed Brown
notmuch-search-filter accepts now accepts an arbitrary query and will
group if necessary so that we get

  tag:inbox AND (gravy OR biscuits)

notmuch-search-filter-tag now handles multiple terms.  All terms in the
query except AND and OR are interpreted as tags.

This version has nice regexes and handles NOT.

Signed-off-by: Jed Brown 
---
 notmuch.el |   27 ++-
 1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 0cabbe2..fdd30ae 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -828,6 +828,10 @@ thread from that buffer can be show when done with this 
one)."
 (defvar notmuch-search-query-string)
 (defvar notmuch-search-oldest-first)

+(defvar notmuch-search-boolean-operator-regexp 
"\\([aA][nN][dD]\\|[oO][rR]\\|[nN][oO][tT]\\)")
+(defvar notmuch-search-valid-term-regexp   "\\([-+_.[:word:]]+\\)")
+(defvar notmuch-search-disjunctive-regexp  "\\<[oO][rR]\\>")
+
 (defun notmuch-search-scroll-up ()
   "Scroll up, moving point to last message in thread if at end."
   (interactive)
@@ -1057,15 +1061,28 @@ search."
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
   (interactive "sFilter search: ")
-  (notmuch-search (concat notmuch-search-query-string " and " query) 
notmuch-search-oldest-first))
+  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp 
query) (concat "( " query " )") query)))
+(notmuch-search (concat notmuch-search-query-string " and " grouped-query) 
notmuch-search-oldest-first)))

-(defun notmuch-search-filter-by-tag (tag)
-  "Filter the current search results based on a single tag.
+(defun notmuch-search-filter-by-tag (query)
+  "Filter the current search results based on one or more tags.

 Runs a new search matching only messages that match both the
-current search results AND that are tagged with the given tag."
+current search results AND that are tagged with the given
+expression involving tags.  For example, the input
+
+  chicken and (gravy or biscuits)
+
+will filter the current search by
+
+  tag:chicken and ( tag:gravy or tag:biscuits )"
   (interactive "sFilter by tag: ")
-  (notmuch-search (concat notmuch-search-query-string " and tag:" tag) 
notmuch-search-oldest-first))
+  (let ((tagged-query (replace-regexp-in-string 
notmuch-search-valid-term-regexp
+   (lambda (match) ; Prepend 
`tag:' to all except boolean operators
+ (if (string-match-p 
notmuch-search-boolean-operator-regexp match)
+ match (concat "tag:" 
match)))
+   query)))
+(notmuch-search-filter tagged-query)))

 (defun notmuch ()
   "Run notmuch to display all mail with tag of 'inbox'"
-- 
1.6.5.3



[notmuch] interesting project!

2009-11-23 Thread Carl Worth
On Mon, 23 Nov 2009 09:08:34 +0200, Dirk-Jan C. Binnema  wrote:
> Well, the counter point to the OOM-problems is that is that in many programs,
> the 'malloc returns NULL'-case is often not very well tested (because it's
> rather hard to test), and that at least on Linux, it's unlikely that malloc
> ever does return NULL. Lennart Poettering wrote this up in some more
> detail[1]. Of course, the requirements for notmuch may be a bit different and
> I definitely don't want to suggest any radical change here after only finding
> out about notmuch a few days ago :)

No problem. I'm glad to discuss things. That's how I learn and find out
whether my decisions are sound or not. :-)

I agree that trying to support OOM doesn't make sense without
testing. But that's why I want to test notmuch with memory-fault
injection. We've been doing this with the cairo library with good
success for a while.

As for "unlikely that malloc ever returns NULL", that's simply a
system-configuration away (just turn off overcommit). And I can imagine
notmuch being used in lots of places, (netbooks, web servers, etc.), so
I do want to make it as robust as possible.

> (BTW, there is a hashtable implementation in libc, (hcreate(3) etc.). Is that
> one not sufficiently 'talloc-friendly'? It's not very user-friendly, but
> that's another matter)

Thanks for mentioning the hash table. The hash table is one of the few
things that I *am* using from glib right now in notmuch. It's got a
couple of bizarre things about it:

1. The simpler-appearing g_hash_table_new function is useless
   for common cases like hashing strings. It will just leak
   memory. So g_hash_table_new_full is the only one worth using.

2. There are two lookup functions, g_hash_table_lookup, and
   g_hash_table_lookup_extended.

   And a program like notmuch really does use the hash table in
   two ways. In the simpler case, we're using the hash to simply
   implement a set, (such as avoiding duplicates in a set of
   tags). In the more complex case, we're associating actual
   objects with the keys, (such as when linking messages
   together into a tree for the thread).

   So, it might make sense if a hash-table interface supported
   these two modes well. What's bizarre about GHashTable though,
   is that in the "just a set" case, we only use NULL as the
   value when inserting. And distinguish "previously inserted
   with NULL" from "never inserted" is the one thing that
   g_hash_table_lookup can't do. So I've only found that I could
   ever use g_hash_table_lookup_extended, (and pass a pair of
   NULLs for the return arguments I don't need).

Fortunately, Eric Anholt spent *his* flight home coding up an nice
implementation of an open-addressed hash designed specifically to be a
tiny little implementation suitable for copying directly into
project. He's testing it with Mesa now, and I might pull it into notmuch
later.

> I could imagine the string functions could replace the ones in talloc. There
> are many more string functions, e.g., for handling file names / paths, which
> are quite useful. Then there are wrappers for gcc'isms (G_UNLIKELY etc.) that
> would make the ones in notmuch unneeded, and a lot of compatibility things
> like G_DIR_SEPARATOR. And the datastructures (GSlice/GList/GHashtable) are
> nice. The UTF8 functionality might come in handy.

Yes. The portability stuff I think is actually interesting. I've thought
it really might make sense to have something that gave you *just* that,
(without a main loop, an object system, several memory allocators or
pieces for making your own memory allocators, etc). I haven't had a
chance to look into gnulib yet, but I'd like to.

As for a list, I almost always find it cleaner to be able to just have
my own list data structures, (to avoid casts, etc.).

And for a hash table, I'm interested in what Eric's doing.

I'm really not prejudiced against using code that's already been
written, (in spite of what might appear I don't feel the need to
re-solve every problem that's already been solved). But I have long
thought that we could have better support for a "C programmers toolkit"
of commonly needed things than we have before.

I definitely like the idea of having tiny, focused libraries that do one
thing and do it well, (and maybe even some things so tiny that they are
actually designed to be copied into the application---like with gnulib
and with Eric's new hash table).

> Anyway, I was just curious, people have survived without GLib before, and if
> you dislike the OOM-strategy, it's a bit of a no-no of course.

Thanks for understanding. :-)

And I enjoy the conversation,

-Carl


[notmuch] [PATCH] Make addresses case insensitive for the purpose of constructing replies.

2009-11-23 Thread Carl Worth
On Mon, 23 Nov 2009 19:29:52 +0100, Jed Brown  wrote:
> The domain is alway case insensitive, but in principle the username is
> case sensitive.  Few systems actually enforce this so I think a good
> default is to treat the entire address as case insensitive, it will
> eliminate a lot of superfluous self-addressed messages and reply from
> the correct address in these cases.

Good call. I've pushed this out now.

-Carl


[notmuch] [PATCH] Stay out of tmp to respect the Maildir spec.

2009-11-23 Thread Carl Worth
On Mon, 23 Nov 2009 21:57:33 +0100, Jed Brown  wrote:
>   if (strcmp (entry->d_name, ".") == 0 ||
>   strcmp (entry->d_name, "..") == 0 ||
> + strcmp (entry->d_name, "tmp") == 0 ||
>   strcmp (entry->d_name, ".notmuch") ==0)

Thanks, Jed!

I've pushed this now.

And sorry about any "file not found" errors anybody is stuck with
now. We'll need to add support for cleaning those up soon, (which is the
same as supporting deleted mail).

-Carl


[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values

2009-11-23 Thread Dirk-Jan Binnema
Hi Jed,

On Mon, Nov 23, 2009 at 4:24 PM, Jed Brown  wrote:

>
>
> But I'm confused here because I don't currently see any warnings with
> gcc-4.4.2.  Actually this must be a bug because I get no warnings for
> the blatantly unused
>
>  malloc(5);
>

Did you try it with -O2? Without optimizations many of the warnings are not
issued.

Best wishes,
Dirk.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/85157f8a/attachment.htm>


[notmuch] Multithreaded access

2009-11-23 Thread Carl Worth
On Mon, 23 Nov 2009 22:07:42 +1100, Peter Wang  wrote:
> I am also toying around with a curses frontend for notmuch :-)
> One thing that I would really like to have is asynchronous search:
> I should be able to begin reading mail even while search results
> are rolling in.

Absolutely! I just coded this up on my plane ride home for notmuch.el
and it is *fantastic*. It takes notmuch from "OK, as long as your
searches don't have a lot of results" to "Blisteringly fast,
regardless of what you're doing."

And it's not like sup, where you page down and then wait for more
search results to page in. Things just keep filling up in the buffer
while you're reading and navigating, just as it should be.

I'll be cleaning this up and pushing it out soon. I'm very excited
about it.

> At the moment I'm using one read-only database_t* and creating multiple
> queries off it.  There's a background thread[1] slurping up  search
> results at a time, then passes them to the main thread.  The main thread
> also handles the pager.  When the user goes to open a thread, it creates
> a separate query_t so that it can look up the messages and their headers
> and filenames.

Hmmm... in my code with emacs, I'm just using separate processes,
(which seems to be working fine). I haven't looked into Xapian's
documentation with regard to threads yet, so I can't actually say how
well notmuch's library work with threads yet.

> A future concern is how to handle tag updates.  Could I open the database
> for writing in one thread, and read-only in another?

Again, I don't know about the threading yet. But you can definitely
open the database read-write in one process while also having it be
opened read-only in another.

-Carl


[notmuch] [PATCH] Return unpropertized strings for filename and message-id

2009-11-23 Thread Tassilo Horn
Hi!

Here's my first patch.  It changes that notmuch-show-get-filename and
notmuch-show-get-message-id return simple strings and not propertited
strings.

Bye,
Tassilo

---
 notmuch.el |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 0cabbe2..c2839c0 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -169,7 +169,7 @@ Unlike builtin `next-line' this version accepts no 
arguments."
 (if (not (looking-at notmuch-show-message-begin-regexp))
(re-search-backward notmuch-show-message-begin-regexp))
 (re-search-forward notmuch-show-id-regexp)
-(buffer-substring (match-beginning 1) (match-end 1
+(buffer-substring-no-properties (match-beginning 1) (match-end 1

 (defun notmuch-show-get-filename ()
   (save-excursion
@@ -177,7 +177,7 @@ Unlike builtin `next-line' this version accepts no 
arguments."
 (if (not (looking-at notmuch-show-message-begin-regexp))
(re-search-backward notmuch-show-message-begin-regexp))
 (re-search-forward notmuch-show-filename-regexp)
-(buffer-substring (match-beginning 1) (match-end 1
+(buffer-substring-no-properties (match-beginning 1) (match-end 1

 (defun notmuch-show-set-tags (tags)
   (save-excursion
-- 
1.6.5.3


[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values

2009-11-23 Thread Jed Brown
On Mon, 23 Nov 2009 18:14:12 +0200, Dirk-Jan Binnema  
wrote:
> Did you try it with -O2? Without optimizations many of the warnings are not
> issued.

Yes,

$ cat > foo.c
#include 
#include 
int main()
{
  malloc(5);
  write(2,0,10);
  return 0;
}
$ gcc -static -std=c89 -O0 -Wall -Wextra -pedantic -o foo foo.c
$ objdump -d -M intel foo |grep -A12 ''
004002a4 :
  4002a4:   55  push   rbp
  4002a5:   48 89 e5movrbp,rsp
  4002a8:   bf 05 00 00 00  movedi,0x5
  4002ad:   e8 6e 61 00 00  call   406420 <__libc_malloc>
  4002b2:   ba 0a 00 00 00  movedx,0xa
  4002b7:   be 00 00 00 00  movesi,0x0
  4002bc:   bf 02 00 00 00  movedi,0x2
  4002c1:   e8 ea a0 00 00  call   40a3b0 <__libc_write>
  4002c6:   b8 00 00 00 00  moveax,0x0
  4002cb:   c9  leave  
  4002cc:   c3  ret
  4002cd:   90  nop
$ gcc -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --prefix=/usr --enable-shared 
--enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-threads=posix 
--mandir=/usr/share/man --infodir=/usr/share/info --enable-__cxa_atexit 
--disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu 
--disable-libstdcxx-pch --with-tune=generic
Thread model: posix
gcc version 4.4.2 (GCC)
$ uname -a
Linux kunyang 2.6.31-ARCH #1 SMP PREEMPT Tue Nov 10 19:01:40 CET 2009 x86_64 
Intel(R) Core(TM)2 Duo CPU P8700 @ 2.53GHz GenuineIntel GNU/Linux


Seems fishy.

Jed


[notmuch] notmuch new: Memory problem

2009-11-23 Thread Dominik Epple
Hi,

2009/11/20 Carl Worth :
> On Fri, 20 Nov 2009 09:56:50 +0100, Dominik Epple  googlemail.com> wrote:
>> Is there a problem with the number of my mails? I currently have over
>> 40.000 Mails... they live currently in mbox files, I created a Maildir
>> with mb2md-3.20.pl.
>
> I'm suspecting that you have some big files in there, (such as indexes
> from some other mail program). We had code in notmuch to detect and
> ignore these, but a recent bug had broken that.
>
> I just fixed this code as of the below commit. So please update and try
> again and let us know if things work any better.

Ok, one of the problems seems to be solved. One can learn from the
info: output that the code actually ignores non-email data. These
files are small and fragments of real mail. Obviously the mb2md code
made errors there.

But I run in a different issue. I have a lot of files in the Maildir
which contain base64 encoded binary data. (Some remote site sends my
its daily backup logs.) Those files are all of 2.4 megabyte in size.
By adding some debug code to notmuch-new.c, I find out that the
program becomes very slow and consumes a lot of memory when adding
these files. I just killed it when it consumed 2 GByte again.

So as you suspected, the problem seems to stem from large files. But
those large files are not indices or stuff like that from different
mail programs, but they are valid emails which contain a lot of
(encoded) binary data.

Perhaps we should be able to configure notmuch such that he ignores
all mails that match specific pattern (like "Subject: Backup logs
from.*")

Regards
Dominik


[notmuch] [patch] Trivial fix for non-root install

2009-11-23 Thread Ingmar Vanhassel
Excerpts from Brett Viren's message of Mon Nov 23 16:31:47 +0100 2009:
> Installing as a normal user fails because the bash completion config
> files try to install into /etc.  This trivial patch fixes this.

NAK

Your patch breaks the more common case of installing as root user. It
now installs into /usr/etc where bash completions most likely won't be
found.

> diff --git a/Makefile.config b/Makefile.config
> index ddc7436..c04d57a 100644
> --- a/Makefile.config
> +++ b/Makefile.config
> @@ -1,3 +1,2 @@
> -prefix = /usr/local
> -bash_completion_dir = /etc/bash_completion.d
> +bash_completion_dir = $(prefix)/etc/bash_completion.d
>  CFLAGS += -DHAVE_VALGRIND
> 
> 
> -Brett.
-- 
Exherbo KDE, X.org maintainer


[notmuch] notmuch new: Memory problem

2009-11-23 Thread Dominik Epple
Hi,

Thanks for your help. Here is the information you requested:

2009/11/20 Carl Worth :
> I'm curious how big your .notmuch directory ended up after this
> operation. (And how that compares in size to the total size of your
> collection of mail.)

I guess you mean these directories:

$ du -sh Maildir
2,8GMaildir
$ cd Maildir
$ du -sh .notmuch
1,1G.notmuch

> That's definitely not too much mail. I think you should expect "notmuch
> new" currently to index on the order of 10 - 100 messages/sec.
>
> Your "notmuch new" process should have been reporting a count once per
> second as it progressed, (at least until things went wrong). How far did
> you see that go?

It started quickly, but its speed decreased, and I interrupted it at
some 4000 messages, if I remember correctly.

Regards
Dominik


[notmuch] Notmuch doesn't index new mails when mail location contains symlinks

2009-11-23 Thread Jed Brown
On Mon, 23 Nov 2009 16:01:41 +0100, Tassilo Horn  
wrote:
> Tassilo Horn  writes:

> I don't have to touch the symlinks or the directories inside the
> locations the symlinks point to, but instead I have to touch the
> top-level directory where the symlinks are contained in.

Ah, it's slightly more subtle.  Notmuch correctly uses stat() instead of
lstat() to check whether the link target changed.  However, mtime for
your mail root directory (containing the symlinks) does not get updated
when the target of the symlinks is updated.  I think the only way to fix
this is to replace the current search (which skips a directory as soon
as it's mtime is older than the database) with one that enters all
directories so that symlinks are actually followed.

Jed


[notmuch] Notmuch doesn't index new mails when mail location contains symlinks

2009-11-23 Thread Jed Brown
On Mon, 23 Nov 2009 15:43:41 +0100, Tassilo Horn  
wrote:
> First, I only touched the two symlinks.

Unfortunately, this actually touched the file pointed to by the symlink,
if you stat the symlink you will see that mtime did not change.

> This didn't help.  Then I used
> "find . -type d | xargs touch" to touch all directories inside the
> directories the symlinks point to.

Actually, this would not have followed the symlinks so it does the same
thing as before.  I think it is actually hard (or not possible) to
change mtime on symlinks under Linux.

> But still no luck.  Finally, I deleted the symlinks and created them
> anew, and then it indexed the 12 new mails that arrived in the
> meantime.

If /var is on the same filesystem, you could use hard links instead of
symlinks.  Otherwise I would just add the appropriate ln -sf in the hook
before notmuch new.

The real solution is for notmuch to check mtime of whatever the
symlink's target.

Jed


[notmuch] Notmuch doesn't index new mails when mail location contains symlinks

2009-11-23 Thread Tassilo Horn
Tassilo Horn  writes:

Hi Mikhail,

>>  TH> Whenever I delete those symlinks and created them anew, the new
>>  TH> mails get indexed with the next "notmuch new".  Of course, I could
>>  TH> create a script that does exactly that, but there should be a
>>  TH> better way, right?
>>
>> Probably mail does not get indexed due to mtime checks. Please try
>> whether touch'ing directory with mailboxes makes it work.
>
> No, it seems that doesn't help either.

Ah, I'm stupid!  I don't have to touch the symlinks or the directories
inside the locations the symlinks point to, but instead I have to touch
the top-level directory where the symlinks are contained in.  Then it
works as expected, AFAICT.

Thanks a lot,
Tassilo


[notmuch] Notmuch doesn't index new mails when mail location contains symlinks

2009-11-23 Thread Tassilo Horn
Mikhail Gusarov  writes:

Hi Mikhail,

>  TH> Whenever I delete those symlinks and created them anew, the new
>  TH> mails get indexed with the next "notmuch new".  Of course, I could
>  TH> create a script that does exactly that, but there should be a
>  TH> better way, right?
>
> Probably mail does not get indexed due to mtime checks. Please try
> whether touch'ing directory with mailboxes makes it work.

No, it seems that doesn't help either.

First, I only touched the two symlinks.  This didn't help.  Then I used
"find . -type d | xargs touch" to touch all directories inside the
directories the symlinks point to.  But still no luck.  Finally, I
deleted the symlinks and created them anew, and then it indexed the 12
new mails that arrived in the meantime.

Bye,
Tassilo


[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values

2009-11-23 Thread Jed Brown
On Mon, 23 Nov 2009 14:19:18 +0100, Karl Wiberg  wrote:
> On Mon, Nov 23, 2009 at 12:11 PM, Dirk-Jan Binnema  
> wrote:
> 
> > On Mon, Nov 23, 2009 at 9:34 AM, Karl Wiberg  wrote:
> >
> > > Didn't the "(void)" suggestion work?
> >
> > I actually preferred that solution, but unfortunately, it didn't
> > stop gcc from complaining...
> 
> Hmpf. I'd argue that that's a gcc bug, forcing the user to use an
> unnecessarily complicated way to pretend to use the return value. Oh
> well.

>From the gcc man page:

   -Wunused-value
   Warn whenever a statement computes a result that is explicitly
   not used. To suppress this warning cast the unused expression
   to void. This includes an expression-statement or the left-
   hand side of a comma expression that contains no side effects.
   For example, an expression such as x[i,j] will cause a
   warning, while x[(void)i,j] will not.

   This warning is enabled by -Wall.


But I'm confused here because I don't currently see any warnings with
gcc-4.4.2.  Actually this must be a bug because I get no warnings for
the blatantly unused

  malloc(5);

with -Wall -Wextra -pedantic.  Anyway, if your system headers specify
__attribute__((warn_unused_result)) for write, then you could be running
into this bug/feature

  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35579


Jed


[notmuch] Notmuch doesn't index new mails when mail location contains symlinks (was: Notmuch doesn't index new mails)

2009-11-23 Thread Tassilo Horn
Tassilo Horn  writes:

Hi all,

I've investigated a bit further.

> [notmuch doesn't index new mails although all directories and files
> are readable and writable.]

In my config, I have:

--8<---cut here---start->8---
[database]
path=/home/horn/Mail/Dovecot
--8<---cut here---end--->8---

In that directory, there are two symlinks pointing to the real mail
location in /var/spool/mail:

--8<---cut here---start->8---
[horn at localhost][~/Mail/Dovecot][0][5213]
[:)] % ll
total 0
lrwxrwxrwx 1 horn horn 34 Nov 23 14:49 fastmail -> 
/var/spool/mail/fastmail/mailboxes
lrwxrwxrwx 1 horn horn 29 Nov 23 14:49 uni -> /var/spool/mail/uni/mailboxes
--8<---cut here---end--->8---

Whenever I delete those symlinks and created them anew, the new mails
get indexed with the next "notmuch new".  Of course, I could create a
script that does exactly that, but there should be a better way, right?

Bye,
Tassilo


[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values

2009-11-23 Thread Karl Wiberg
On Mon, Nov 23, 2009 at 12:11 PM, Dirk-Jan Binnema  
wrote:

> On Mon, Nov 23, 2009 at 9:34 AM, Karl Wiberg  wrote:
>
> > Didn't the "(void)" suggestion work?
>
> I actually preferred that solution, but unfortunately, it didn't
> stop gcc from complaining...

Hmpf. I'd argue that that's a gcc bug, forcing the user to use an
unnecessarily complicated way to pretend to use the return value. Oh
well.

-- 
Karl Wiberg, kha at treskal.com
   subrabbit.wordpress.com
   www.treskal.com/kalle


[notmuch] [PATCH] New function notmuch-search-operate-all: operate on all messages in the current query.

2009-11-23 Thread Jed Brown
On Mon, 23 Nov 2009 05:14:25 +0100, Carl Worth  wrote:
> Second, I like that you just used the search string again, (as opposed
> to just walking through the buffer looking at thread IDs). That seems
> elegant.

It was *easy*.

> First, this creates a race condition in that the user will rightly
> expect to only be adding/removing tags from the visible results. But if
> new mail has been incorporated between creating the current view and
> running '*' then threads could be tagged that were never seen and that
> could be problematic.

Agreed and I had also thought of the case you described.  Note that
Gmail does not solve the race condition.  When in summary mode:

* Marking a thread as read applies to all messages in the thread.  The
  thread contents are being updated concurrently so you may mark threads
  you have already seen.

* Same story with archiving (aka. remove inbox).

* Starring a thread applies to the last message in the thread, this
  could be a newly arrived message that is not currently displayed.

I think that handling a concurrent changes to the match results is a
somewhat hard problem.  You have to store the message ids of everything
in the current query if you want to avoid the race.

> Second, since we're in the search view which shows threads, we should
> really be operating on threads. But this tag command won't work like the
> '+' and '-' commands in this buffer. Those commands will add/remove a
> tag to/from every message in the thread[*]. The new '*' command, however
> will only be changing tags on messages that match the query.

I'm not convinced that we want to operate on the entire thread.
Applying the tag only to the matched messages is enough to find the
thread, and it may really be desirable to only have it applied to
certain messages in the thread.  For example, I might have constructed
an elaborate query to find five messages, including a couple that are
burried in 100-message threads in which case I would definitely not want
to tag entire threads.

> So I think we should fix both of these issues by looping over each line
> of the buffer and calling (notmuch-search-add-tag) or
> (notmuch-search-remove-tag).

Presumably you don't mean this literally because that would be horribly
slow.  What you want is to gather up all the message ids in all the
threads with at least one message matching the current query (and
currently displayed).  I think this is only possible if notmuch-search
holds message IDs for everything in the matched threads.  If we are
happy to just tag the matched messages instead of the entire thread, we
would only store the message ids for the matched messages.

> Oh, here's one: We could add something like "notmuch tag --expecting=
> 1/23 " that would not do the tag unless the search string
> matched 1 message out of 23 total messages in the thread. Then we could
> give a warning to the user.

I like this, but it still presents a minor race condition (suppose
another client swaps the unread tag on two messages in the same thread).
The only way to guarantee that you are operating on the displayed
messages is to store their message ids.

> That works for the single-thread case, but the warning would be harder
> for the user to deal with in the '*' case. Or maybe not---the emacs
> function could just stop on the first line with the error and then the
> user would see what's going on.

If you can implement notmuch tag --expecting with similar efficiency to
the present, then I would vote for notifying the user and asking for
confirmation if the number of matches has changed.  This would be
significantly safer than what Gmail does which ought to be sufficient
for now given the age of notmuch.


Jed


[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values

2009-11-23 Thread Dirk-Jan Binnema
On Mon, Nov 23, 2009 at 9:34 AM, Karl Wiberg  wrote:

> On Mon, Nov 23, 2009 at 7:20 AM, Dirk-Jan C. Binnema
>  wrote:
>
> > +ssize_t ignored;
> > static char msg[] = "Stopping... \n";
> > -write(2, msg, sizeof(msg)-1);
> > +
> > +ignored = write(2, msg, sizeof(msg)-1);
> > interrupted = 1;
> >  }
>
> Didn't the "(void)" suggestion work?
>
>
I actually preferred that solution, but unfortunately, it didn't stop gcc
from complaining...

Best wishes,
Dirk.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/7ea82ed8/attachment.htm>


[notmuch] [PATCH] Make search filters handle disjunctive queries.

2009-11-23 Thread Jed Brown
notmuch-search-filter accepts now accepts an arbitrary query and will
group if necessary so that we get

  tag:inbox AND (gravy OR biscuits)

notmuch-search-filter-tag now handles multiple terms.  All terms in the
query except AND and OR are interpreted as tags.

Signed-off-by: Jed Brown 
---
 notmuch.el |   23 ++-
 1 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 0cabbe2..43e0566 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -1057,15 +1057,28 @@ search."
 Runs a new search matching only messages that match both the
 current search results AND the additional query string provided."
   (interactive "sFilter search: ")
-  (notmuch-search (concat notmuch-search-query-string " and " query) 
notmuch-search-oldest-first))
+  (let ((grouped-query (if (string-match-p "\\<[oO][rR]\\>" query) (concat "( 
" query " )") query)))
+(notmuch-search (concat notmuch-search-query-string " and " grouped-query) 
notmuch-search-oldest-first)))

-(defun notmuch-search-filter-by-tag (tag)
-  "Filter the current search results based on a single tag.
+(defun notmuch-search-filter-by-tag (query)
+  "Filter the current search results based on one or more tags.

 Runs a new search matching only messages that match both the
-current search results AND that are tagged with the given tag."
+current search results AND that are tagged with the given
+expression involving tags.  For example, the input
+
+  chicken and (gravy or biscuits)
+
+will filter the current search by
+
+  tag:chicken and ( tag:gravy or tag:biscuits )"
   (interactive "sFilter by tag: ")
-  (notmuch-search (concat notmuch-search-query-string " and tag:" tag) 
notmuch-search-oldest-first))
+  (let ((tagged-query (replace-regexp-in-string "\\([_\+\-]\\|\\w\\)+"
+   (lambda (match) ; Prepend 
`tag:' to all matches except AND and OR
+ (if (string-match-p 
"\\([aA][nN][dD]\\)\\|\\([oO][rR]\\)" match)
+ match (concat "tag:" 
match)))
+   query)))
+(notmuch-search-filter tagged-query)))

 (defun notmuch ()
   "Run notmuch to display all mail with tag of 'inbox'"
-- 
1.6.5.3



[notmuch] _notmuch_message_create_for_message_id makes extra call to notmuch_database_find_message

2009-11-23 Thread Keith Packard

Looking at _notmuch_message_create_for_message_id, the first thing it
does is call notmuch_database_find_message, but the returned 'message'
is never used. I haven't tried, but I suspect this call could just be
removed.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/71f548b8/attachment.pgp>


[notmuch] [patch] Trivial fix for non-root install

2009-11-23 Thread Alec Berryman
Brett Viren on 2009-11-23 10:31:47 -0500:

> Installing as a normal user fails because the bash completion config
> files try to install into /etc.  This trivial patch fixes this.

I worked around this by using $DESTDIR as the prefix and unsetting
prefix during the install.



[notmuch] [PATCH] Add tests to configure script to detect strndup and getline

2009-11-23 Thread Jeffrey C. Ollie
Add some simple tests to the configure script to detect strndup and
getline.  It's not important that the tests run, just that they
compile and link without any errors.

Signed-off-by: Jeffrey C. Ollie 
---
 configure |   20 +++-
 getlinetest.c |   13 +
 strnduptest.c |   10 ++
 3 files changed, 42 insertions(+), 1 deletions(-)
 create mode 100644 getlinetest.c
 create mode 100644 strnduptest.c

diff --git a/configure b/configure
index b4770ec..44c1700 100755
--- a/configure
+++ b/configure
@@ -118,6 +118,24 @@ EOF
 exit 1
 fi

+if ! gcc -o strnduptest strnduptest.c > /dev/null 2>&1
+then
+echo "Checking for strndup... No."
+strndup=-Dstrndup=_notmuch_strndup
+else
+echo "Checking for strndup... Yes."
+fi
+rm -f strnduptest
+
+if ! gcc -o getlinetest getlinetest.c > /dev/null 2>&1
+then
+echo "Checking for getline... No."
+getline=-Dgetline=_notmuch_getline
+else
+echo "Checking for getline... Yes."
+fi
+rm -f getlinetest
+
 cat < Makefile.config <
+#include 
+
+int main()
+{
+  ssize_t count = 0;
+  size_t n = 0;
+  char **lineptr = NULL;
+  FILE *stream = NULL;
+
+  count = getline(lineptr, , stream);
+}
diff --git a/strnduptest.c b/strnduptest.c
new file mode 100644
index 000..97c7c80
--- /dev/null
+++ b/strnduptest.c
@@ -0,0 +1,10 @@
+#include 
+
+int main()
+{
+  char *d;
+  const char *s = "";
+  size_t n = 0;
+
+  d = strndup(s, n);
+}
-- 
1.6.5.2



[notmuch] Notmuch doesn't index new mails

2009-11-23 Thread Tassilo Horn
Hi all,

after setting up notmuch, initially indexing all my mail, and removing
the inbox and unread tags thereafter, now I recognize that notmuch
doesn't index new mail.

--8<---cut here---start->8---
% notmuch new --verbose
No new mail---and that's not much.
--8<---cut here---end--->8---

I did check that there's really new mail.

In the man page, it is mentioned, that notmuch skips directories that
are read-only.  So now all my folders are "drwxrwxr-x mail mail", and I
am in the mail group.

But still, notmuch doesn't index new mails.

I assumed that the mail files also have to be writable.  So I changed
them to "-rw-rw-r-- mail mail", but still no luck.

Any ideas what might be the problem?

Bye,
Tassilo


[notmuch] notsomuch, a dummy curses ui

2009-11-23 Thread Ruben Pollan
Hi notmuch community,

As I'm not an emacs user, I started to play with the code to see what are the
power of notmuch. I create a simple ncurses ui:
http://gitorious.org/notsomuch

Up to now it don't do much, just display searches and threads. It don't even
display the content of the emails. I guess I'll be playing with it for some
weeks, but not sure jet if I'll try to create a proper program or I'll drop it
soon.


PS: I have to try the vim pluggin, maybe that could be my email reader in the
future.

-- 
Rub?n Poll?n  | jabber:meskio at jabber.org
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 No vamos a reivindicar nada,
no vamos a pedir nada.
Tomaremos, okuparemos.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/69b5cf65/attachment.pgp>


[notmuch] [RFC PATCH -V2] notmuch: Add support for multiple maildirs

2009-11-23 Thread Aneesh Kumar K.V
On Mon, Nov 23, 2009 at 04:51:34AM +0100, Carl Worth wrote:
> Finally, (and maybe I should have started with this), what's the actual
> use case here? Is it difficult to just arrange all mail to be under one
> top-level directory, (perhaps just using symlinks even).
> 

Ok i switched to using a separate directory for notmuch and symlink the
interested folders into that. So you can ignore the patch

-aneesh


[notmuch] [PATCH -v3] notmuch.el: Add face support to search and show mode

2009-11-23 Thread Aneesh Kumar K.V
This add two faces, notmuch-show-subject-face and
notmuch-tag-face. The first face is used to show the subject
line in the notmuch-show-mode and the second one to show tags
in the notmuch-search-mode.

We can selectively highlight each tag by setting notmuch-tag-face-alist as below

(defface notmuch-tag-unread-face
 'class color) (background light)) (:foreground "goldenrod" :bold t))
(((class color) (background dark)) (:foreground "goldenrod" :bold t)))
  "Notmuch search mode face used to highligh tags.")

(defface notmuch-tag-inbox-face
 'class color) (background light)) (:foreground "red" :bold t))
(((class color) (background dark)) (:foreground "red" :bold t)))
  "Notmuch search mode face used to highligh tags.")

(setq notmuch-tag-face-alist '(("unread" . 'notmuch-tag-unread-face)
 ("inbox" . 'notmuch-tag-inbox-face)))
(require 'notmuch)

Signed-off-by: Aneesh Kumar K.V 
---
 notmuch.el |   40 ++--
 1 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 1f24461..2aa6d5a 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -686,6 +686,18 @@ which this thread was originally shown."
   (force-window-update)
   (redisplay t))

+(defface notmuch-show-subject-face
+ 'class color) (background light)) (:foreground "yellow" :bold t))
+(((class color) (background dark)) (:foreground "yellow" :bold t)))
+  "Notmuch show mode face used to highligh subject line."
+  :group 'notmuch)
+
+(defvar notmuch-show-font-lock-keywords
+  (list ;; header in font-lock-type-face
+   (list "\\(Subject:.*$\\)"
+'(1  'notmuch-show-subject-face)))
+  "Additonal expression to hightlight in notmuch-show-mode")
+
 ;;;###autoload
 (defun notmuch-show-mode ()
   "Major mode for viewing a thread with notmuch.
@@ -726,7 +738,9 @@ view, (remove the \"inbox\" tag from each), with
   (use-local-map notmuch-show-mode-map)
   (setq major-mode 'notmuch-show-mode
mode-name "notmuch-show")
-  (setq buffer-read-only t))
+  (setq buffer-read-only t)
+  (set (make-local-variable 'font-lock-defaults)
+ '(notmuch-show-font-lock-keywords t)))

 ;;;###autoload

@@ -855,6 +869,17 @@ thread from that buffer can be show when done with this 
one)."
   (goto-char (point-max))
   (forward-line -1))

+(defface notmuch-tag-face
+ 'class color) (background light)) (:foreground "goldenrod" :bold t))
+(((class color) (background dark)) (:foreground "goldenrod" :bold t)))
+  "Notmuch search mode face used to highligh tags."
+  :group 'notmuch)
+
+(defvar notmuch-tag-face-alist nil
+  "List containing the tag list that need to be highlighed")
+
+(defvar notmuch-search-font-lock-keywords  nil)
+
 ;;;###autoload
 (defun notmuch-search-mode ()
   "Major mode for searching mail with notmuch.
@@ -885,7 +910,18 @@ global search.
   (setq truncate-lines t)
   (setq major-mode 'notmuch-search-mode
mode-name "notmuch-search")
-  (setq buffer-read-only t))
+  (setq buffer-read-only t)
+  (if (not notmuch-tag-face-alist)
+  (add-to-list 'notmuch-search-font-lock-keywords (list
+   "\\(([^)]*)$\\)" '(1  'notmuch-tag-face)))
+(progn
+  (setq notmuch-search-tags (mapcar 'car notmuch-tag-face-alist))
+  (loop for notmuch-search-tag  in notmuch-search-tags
+do (add-to-list 'notmuch-search-font-lock-keywords (list
+   (concat "\\(" notmuch-search-tag "\\)")
+   `(1  ,(cdr (assoc notmuch-search-tag 
notmuch-tag-face-alist
+  (set (make-local-variable 'font-lock-defaults)
+ '(notmuch-search-font-lock-keywords t)))

 (defun notmuch-search-find-thread-id ()
   (save-excursion
-- 
1.6.5.2.74.g610f9



[notmuch] [patch] Trivial fix for non-root install

2009-11-23 Thread Jameson Rollins
On Mon, Nov 23, 2009 at 04:41:23PM +0100, Ingmar Vanhassel wrote:
> Excerpts from Brett Viren's message of Mon Nov 23 16:31:47 +0100 2009:
> > Installing as a normal user fails because the bash completion config
> > files try to install into /etc.  This trivial patch fixes this.
>
> Your patch breaks the more common case of installing as root user. It
> now installs into /usr/etc where bash completions most likely won't be
> found.

I submitted a patch similar to Ingmar's the other day.  I actually
feel like the more common case is to install it locally as a local
user, especially during early development.

jamie.

> > diff --git a/Makefile.config b/Makefile.config
> > index ddc7436..c04d57a 100644
> > --- a/Makefile.config
> > +++ b/Makefile.config
> > @@ -1,3 +1,2 @@
> > -prefix = /usr/local
> > -bash_completion_dir = /etc/bash_completion.d
> > +bash_completion_dir = $(prefix)/etc/bash_completion.d
> >  CFLAGS += -DHAVE_VALGRIND
> > 
> > 
> > -Brett.
> -- 
> Exherbo KDE, X.org maintainer
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/0ea9b7af/attachment.pgp>


[notmuch] [patch] Trivial fix for non-root install

2009-11-23 Thread Brett Viren
Installing as a normal user fails because the bash completion config
files try to install into /etc.  This trivial patch fixes this.

diff --git a/Makefile.config b/Makefile.config
index ddc7436..c04d57a 100644
--- a/Makefile.config
+++ b/Makefile.config
@@ -1,3 +1,2 @@
-prefix = /usr/local
-bash_completion_dir = /etc/bash_completion.d
+bash_completion_dir = $(prefix)/etc/bash_completion.d
 CFLAGS += -DHAVE_VALGRIND


-Brett.


[notmuch] [PATCH] Make search filters handle disjunctive queries.

2009-11-23 Thread Keith Packard
On Mon, 23 Nov 2009 19:07:23 +0100, Jed Brown  wrote:

> notmuch-search-filter accepts now accepts an arbitrary query and will
> group if necessary so that we get
> 
>   tag:inbox AND (gravy OR biscuits)
> 
> notmuch-search-filter-tag now handles multiple terms.  All terms in the
> query except AND and OR are interpreted as tags.

Remember to split patches which do more than one thing into separate
commits.

> +  (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp 
> query) (concat "( " query " )") query)))
> +(notmuch-search (concat notmuch-search-query-string " and " 
> grouped-query) notmuch-search-oldest-first)))

Is there some reason not to just always add the parens?

> +  (let ((tagged-query (replace-regexp-in-string 
> notmuch-search-valid-term-regexp
> + (lambda (match) ; Prepend 
> `tag:' to all except boolean operators
> +   (if (string-match-p 
> notmuch-search-boolean-operator-regexp match)
> +   match (concat "tag:" 
> match)))
> + query)))

This seems useful; how does it deal with the tag completion stuff?

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/59d04243/attachment.pgp>


[notmuch] interesting project!

2009-11-23 Thread Dirk-Jan C. Binnema
Hi Carl,

> "Carl" == Carl Worth  writes:

Carl> On Sun, 22 Nov 2009 14:23:10 +0200, Dirk-Jan C. Binnema
Carl>  wrote:
>> A small question: it seems that notmuch is avoiding the use of GLib 
directly
>> (of course, it depend on it anyway through GMime); is this because of
>> OOM-handling? It'd be nice if GLib could be used, it would make some 
things
>> quite a bit easier.

Carl> It's true that I don't like the OOM handling in glib. I also think 
that
Carl> glib tries to be too many different things at the same time. And
Carl> finally, having some talloc-friendly data structures (like a 
hash-table)
Carl> would be really nice.

Well, the counter point to the OOM-problems is that is that in many programs,
the 'malloc returns NULL'-case is often not very well tested (because it's
rather hard to test), and that at least on Linux, it's unlikely that malloc
ever does return NULL. Lennart Poettering wrote this up in some more
detail[1]. Of course, the requirements for notmuch may be a bit different and
I definitely don't want to suggest any radical change here after only finding
out about notmuch a few days ago :)

(BTW, there is a hashtable implementation in libc, (hcreate(3) etc.). Is that
one not sufficiently 'talloc-friendly'? It's not very user-friendly, but
that's another matter)

Carl> In the meantime, as you say, we're already linking with glib because 
of
Carl> GMime, so there's really no reason not to call functions that are 
there
Carl> and that do what we want. What kinds of things were you thinking of 
that
Carl> would be easier with glib?

I could imagine the string functions could replace the ones in talloc. There
are many more string functions, e.g., for handling file names / paths, which
are quite useful. Then there are wrappers for gcc'isms (G_UNLIKELY etc.) that
would make the ones in notmuch unneeded, and a lot of compatibility things
like G_DIR_SEPARATOR. And the datastructures (GSlice/GList/GHashtable) are
nice. The UTF8 functionality might come in handy.

Anyway, I was just curious, people have survived without GLib before, and if
you dislike the OOM-strategy, it's a bit of a no-no of course.

Best wishes,
Dirk.


[1] http://article.gmane.org/gmane.comp.audio.jackit/19998

-- 
Dirk-Jan C. Binnema  Helsinki, Finland
e:djcb at djcbsoftware.nl   w:www.djcbsoftware.nl
pgp: D09C E664 897D 7D39 5047 A178 E96A C7A1 017D DA3C


[notmuch] How to index /var/spool/mail with notmuch

2009-11-23 Thread Tassilo Horn
Carl Worth  writes:

Hi Carl,

>> Unfortunately, there are some dovecot internal files, which should
>> neither be indexed by notmuch, and which have 600 permissions for the
>> mail user.  And that's where notmuch errors and stops indexing. :-(
>
> Hi Tassilo, welcome to notmuch!
>
> I'm glad you found a workaround for this problem, (thanks Jed!).

Trying out notmuch already cashed out. ;-)

> But perhaps these errors should be made into warnings instead? Any
> thoughts on that anyone?

I think so.  For other dovecot internal index files it already says
something like "Ignoring non-mail file foobar.idx" and simply skips that
file.  I think that's the right thing to do for files where it has no
read permissions for, too.

>> All "real" mail files are named "u.", so it would be cool if
>> I could provide a pattern to notmuch matching all files I'd like to
>> index.  And maybe the other way round (a blacklist pattern) would be
>> useful, too.
>
> I've been planning on having a blacklist pattern for a while.
> Originally, the only difficulty in implementing it was that we had
> nowhere to store configuration information.  But we have a
> configuration file now, so this would be a pretty easy thing to
> implement.
>
> It's not as obvious that a whitelist pattern would be as widely
> useful, but it would be possible too.

Well, for dovecot users using the dbox format, a whitelist pattern would
be much simpler because of the coherent mail file naming.  But I could
live with a blacklist pattern, too.

Bye,
Tassilo


[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values

2009-11-23 Thread Karl Wiberg
On Mon, Nov 23, 2009 at 7:20 AM, Dirk-Jan C. Binnema
 wrote:

> + ? ?ssize_t ignored;
> ? ? static char msg[] = "Stopping... ? ? ? ? \n";
> - ? ?write(2, msg, sizeof(msg)-1);
> +
> + ? ?ignored = write(2, msg, sizeof(msg)-1);
> ? ? interrupted = 1;
> ?}

Didn't the "(void)" suggestion work?

-- 
Karl Wiberg, kha at treskal.com
   subrabbit.wordpress.com
   www.treskal.com/kalle


[notmuch] [PATCH 2/2] * avoid gcc 4.4.1 compiler warning due to ignored 'fflush' return value

2009-11-23 Thread Dirk-Jan C. Binnema


---
 notmuch-setup.c |   13 +++--
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/notmuch-setup.c b/notmuch-setup.c
index d06fbf8..c50f812 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -100,12 +100,13 @@ notmuch_setup_command (unused (void *ctx),
 unsigned int i;
 int is_new;

-#define prompt(format, ...)\
-do {   \
-   printf (format, ##__VA_ARGS__); \
-   fflush (stdout);\
-   getline (, _size, stdin); \
-   chomp_newline (response);   \
+#define prompt(format, ...)\
+do {   \
+   int ignored;\
+   printf (format, ##__VA_ARGS__); \
+   fflush (stdout);\
+   ignored = getline (, _size, stdin);   \
+   chomp_newline (response);   \
 } while (0)

 config = notmuch_config_open (ctx, NULL, _new);
-- 
1.6.3.3



[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values

2009-11-23 Thread Dirk-Jan C. Binnema
From: Dirk-Jan C. Binnema 
Date: Mon, 23 Nov 2009 08:03:35 +0200


---
 notmuch-new.c |4 +++-
 notmuch-tag.c |4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/notmuch-new.c b/notmuch-new.c
index a2b30bd..3d04efa 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -35,8 +35,10 @@ static volatile sig_atomic_t interrupted;
 static void
 handle_sigint (unused (int sig))
 {
+ssize_t ignored;
 static char msg[] = "Stopping... \n";
-write(2, msg, sizeof(msg)-1);
+
+ignored = write(2, msg, sizeof(msg)-1);
 interrupted = 1;
 }

diff --git a/notmuch-tag.c b/notmuch-tag.c
index e2311f6..ec98c3b 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -25,8 +25,10 @@ static volatile sig_atomic_t interrupted;
 static void
 handle_sigint (unused (int sig))
 {
+ssize_t ignored;
+   
 static char msg[] = "Stopping... \n";
-write(2, msg, sizeof(msg)-1);
+ignored = write(2, msg, sizeof(msg)-1);
 interrupted = 1;
 }

-- 
1.6.3.3



[notmuch] [PATCH] makefile: Tell echo to interpret escape sequences.

2009-11-23 Thread Karl Wiberg
On Mon, Nov 23, 2009 at 3:41 AM, Carl Worth  wrote:

> It's a shame that simple things like "echo" aren't easy to use portably.
> (And yes, I know that autoconf has a bunch of tests for echo, such as
> how to get the behavior of "echo -n", etc.)

I think the standard workaround is to use "printf" instead.

-- 
Karl Wiberg, kha at treskal.com
   subrabbit.wordpress.com
   www.treskal.com/kalle


[notmuch] OpenPGP support

2009-11-23 Thread Jameson Graef Rollins
Hi, folks.  I know it's a hairy problem, but has anyone started
looking into OpenPGP support for notmuch?

jamie.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/d315bb63/attachment.pgp>


[notmuch] [PATCH] Add private implementations of strndup and getline.

2009-11-23 Thread Jeffrey C. Ollie
Add private implementations of strndup and getline for those platforms
that don't have them (notably Mac OS X) no matter what preprocessor
symbols you define.

Signed-off-by: Jeffrey C. Ollie 
---
 lib/xutil.c |   99 +++
 lib/xutil.h |6 +++
 2 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/lib/xutil.c b/lib/xutil.c
index 6fa5eb0..61467f1 100644
--- a/lib/xutil.c
+++ b/lib/xutil.c
@@ -79,6 +79,105 @@ xstrdup (const char *s)
 return ret;
 }

+/* Mac OS X don't have strndup even if _GNU_SOURCE is defined */
+char *
+_notmuch_strndup (const char *s, size_t n)
+{
+size_t len = strlen (s);
+char *ret;
+
+if (len <= n)
+   return strdup (s);
+
+ret = malloc(n + 1);
+strncpy(ret, s, n);
+ret[n] = '\0';
+return ret;
+}
+
+/* getline implementation is copied from glibc. */
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+ssize_t
+_notmuch_getline (char **lineptr, size_t *n, FILE *fp)
+{
+ssize_t result;
+size_t cur_len = 0;
+
+if (lineptr == NULL || n == NULL || fp == NULL)
+{
+   errno = EINVAL;
+   return -1;
+}
+
+if (*lineptr == NULL || *n == 0)
+{
+   *n = 120;
+   *lineptr = (char *) malloc (*n);
+   if (*lineptr == NULL)
+   {
+   result = -1;
+   goto end;
+   }
+}
+
+for (;;)
+{
+   int i;
+
+   i = getc (fp);
+   if (i == EOF)
+   {
+   result = -1;
+   break;
+   }
+
+   /* Make enough space for len+1 (for final NUL) bytes.  */
+   if (cur_len + 1 >= *n)
+   {
+   size_t needed_max =
+   SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+   size_t needed = 2 * *n + 1;   /* Be generous. */
+   char *new_lineptr;
+
+   if (needed_max < needed)
+   needed = needed_max;
+   if (cur_len + 1 >= needed)
+   {
+   result = -1;
+   goto end;
+   }
+
+   new_lineptr = (char *) realloc (*lineptr, needed);
+   if (new_lineptr == NULL)
+   {
+   result = -1;
+   goto end;
+   }
+
+   *lineptr = new_lineptr;
+   *n = needed;
+   }
+
+   (*lineptr)[cur_len] = i;
+   cur_len++;
+
+   if (i == '\n')
+   break;
+}
+(*lineptr)[cur_len] = '\0';
+result = cur_len ? (ssize_t) cur_len : result;
+
+end:
+return result;
+}
+
 char *
 xstrndup (const char *s, size_t n)
 {
diff --git a/lib/xutil.h b/lib/xutil.h
index b973f7d..d13259a 100644
--- a/lib/xutil.h
+++ b/lib/xutil.h
@@ -39,6 +39,12 @@ char *
 xstrdup (const char *s);

 char *
+_notmuch_strndup (const char *s, size_t n);
+
+ssize_t
+_notmuch_getline (char **lineptr, size_t *n, FILE *stream);
+
+char *
 xstrndup (const char *s, size_t n);

 void
-- 
1.6.5.2



[notmuch] [PATCH] Mac OS X compatibility fixes

2009-11-23 Thread Jeffrey C. Ollie
Here's a patch that adds private implementations of strndup and
getline.  They are unconditionally compiled so that compiler errors in
these functions can be detected on any platform, even those that
provide strndup and getline in the standard library.  I'll have a
patch that handles the strndup/getline detection later today (I've
already done it in SCons, just need to figure out how I want to do it
in plain shell for the current configure script).



[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 19:52:00 -0800, Keith Packard  wrote:
> I'd take 'x' for 'return to search view; otherwise you're going to wear
> out my pinky reaching for the shift key. That leaves us with three
> commands:
> 
> 'a': advance to next message, archiving current thread, marking read
> messages. ('A' forces all messages in thread to be marked as read)
> 
> 'x': exit to search view, archiving current thread, marking read
> messages. ('X' forces all messages in thread to be marked as read)
> 
> 'q': quit back to search view, leaving thread tags unmodified.

OK. You win. That looks pretty good to me.

> There's a slightly weird asymmetry here -- there's no way to advance to
> the next thread and not mark messages.

Well, there's "q, n, RET" at least. ;-)

-Carl


[notmuch] [PATCH] Add SCons build files.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 22:36:30 -0600, Jeffrey Ollie  wrote:
> Well, to me, part of the appeal of SCons is that it doesn't generate
> Makefiles.This article is a little old, but the first three
> sections are a pretty good rundown on the limitations of Make.
> 
> http://www.scons.org/wiki/FromMakeToScons

Not very convincing to me at least. Half of it is limitations of various
make implementations, (notmuch is definitely not trying to be portable
across those---it uses GNU make). The other half is about problems in
how make is often used, (like slow recursive make runs, or incomplete
dependencies---but we've got a nice non-recursive make setup in notmuch
and good dependency generation).

It is true that make is doing timestamp-based checks rather than
content-based, but things like this are things that people are quite
familiar in deailing with.

> If you really want a tool that generates Makefiles, take a look at
> CMake.

No I don't want a tool to generate Makefiles. I want to write the
Makefiles, (which I've done). I'm willing to have a tool to create the
configuration, (really just some variables accessible at
compile-time). Right now we're storing these in a Makefile snippet named
"Makefile.config" but we could just as easily be putting them in
"config.h".

> I think that having multiple different configuration systems would be
> pretty awful, especially if people make changes to their favourite
> configuration system and hope that someone else fixes the others.

It's early times. I'm willing to entertain different ideas and have
people propose different means of doing the configure step. Long-term
we'll likely only have one supported thing.

> It would seem to me that we would be re-inventing a lot of the work
> already done by other people.

But there's really so little to invent here. It's just not that hard to
do the kinds of configuration that notmuch needs. So far we've got a few
pkg-config checks and that gets us a long ways. Beyond that, the only
portability improvements requested so far will require only the
following from configure:

  * Find which of the compiler warning flags we want are available.

  * Find whether we have some particular library functions are
available.

And for these steps, all we have to do is to *compile* some test
programs. And compiling programs is something our build system knows how
to do already (since that's all it does). So I'm just not seeing that
we'll spend much time reinventing anything.

-Carl


[notmuch] [PATCH] Handle message renames in mail spool

2009-11-23 Thread Mikhail Gusarov
In order to handle message renames the following changes were deemed necessary:

* Mtime check on individual files was disabled. As files may be moved around
without changing their mtime, it's necessary to parse them even if they appear
old in case old message was moved. mtime check on directories was kept as moving
files changes mtime of directory.

* If message being parsed is already found in database under different path,
then this message is considered to be moved, path is updated in database and
this file does not undergo further processing.

Note that after applying this patch notmuch still does not handle copying files
(which is harmless, database will point to the last copy of message found during
'notmuch new') and deleting files (which is more serious, as dangling entries
will show up in searches).

Signed-off-by: Mikhail Gusarov 
---
 lib/database.cc |   21 +++-
 notmuch-new.c   |   92 ++
 2 files changed, 56 insertions(+), 57 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index 2c90019..d88efbe 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -990,20 +990,23 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
_notmuch_message_set_filename (message, filename);
_notmuch_message_add_term (message, "type", "mail");
+
+   ret = _notmuch_database_link_message (notmuch, message, 
message_file);
+   if (ret)
+   goto DONE;
+
+   date = notmuch_message_file_get_header (message_file, "date");
+   _notmuch_message_set_date (message, date);
+
+   _notmuch_message_index_file (message, filename);
+   } else if (strcmp(notmuch_message_get_filename(message), filename)) {
+   /* Message file has been moved/renamed */
+   _notmuch_message_set_filename (message, filename);
} else {
ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
goto DONE;
}

-   ret = _notmuch_database_link_message (notmuch, message, message_file);
-   if (ret)
-   goto DONE;
-
-   date = notmuch_message_file_get_header (message_file, "date");
-   _notmuch_message_set_date (message, date);
-
-   _notmuch_message_index_file (message, filename);
-
_notmuch_message_sync (message);
 } catch (const Xapian::Error ) {
fprintf (stderr, "A Xapian exception occurred adding message: %s.\n",
diff --git a/notmuch-new.c b/notmuch-new.c
index 0dd2784..d16679c 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -174,54 +174,50 @@ add_files_recursive (notmuch_database_t *notmuch,
}

if (S_ISREG (st->st_mode)) {
-   /* If the file hasn't been modified since the last
-* add_files, then we need not look at it. */
-   if (path_dbtime == 0 || st->st_mtime > path_dbtime) {
-   state->processed_files++;
-
-   status = notmuch_database_add_message (notmuch, next, );
-   switch (status) {
-   /* success */
-   case NOTMUCH_STATUS_SUCCESS:
-   state->added_messages++;
-   tag_inbox_and_unread (message);
-   break;
-   /* Non-fatal issues (go on to next file) */
-   case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
-   /* Stay silent on this one. */
-   break;
-   case NOTMUCH_STATUS_FILE_NOT_EMAIL:
-   fprintf (stderr, "Note: Ignoring non-mail file: %s\n",
-next);
-   break;
-   /* Fatal issues. Don't process anymore. */
-   case NOTMUCH_STATUS_READONLY_DATABASE:
-   case NOTMUCH_STATUS_XAPIAN_EXCEPTION:
-   case NOTMUCH_STATUS_OUT_OF_MEMORY:
-   fprintf (stderr, "Error: %s. Halting processing.\n",
-notmuch_status_to_string (status));
-   ret = status;
-   goto DONE;
-   default:
-   case NOTMUCH_STATUS_FILE_ERROR:
-   case NOTMUCH_STATUS_NULL_POINTER:
-   case NOTMUCH_STATUS_TAG_TOO_LONG:
-   case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
-   case NOTMUCH_STATUS_LAST_STATUS:
-   INTERNAL_ERROR ("add_message returned unexpected value: 
%d",  status);
-   goto DONE;
-   }
-
-   if (message) {
-   notmuch_message_destroy (message);
-   message = NULL;
-   }
-
-   if (do_add_files_print_progress) {
-   do_add_files_print_progress = 0;
-   add_files_print_progress (state);
-   }
-   }
+

[notmuch] notmuch 'index' mode.

2009-11-23 Thread Carl Worth
On Fri, 20 Nov 2009 23:35:29 -0800, Keith Packard  wrote:
> I posted a patch adding an 'index' mode to notmuch and though I'd
> explain my idea. Most mail systems provide a 'folder view' mode which
> displays the set of folders and a count of messages in each folder. I
> used this myself as the first sort of which messages I want to read.

I've just pushed this set of patches out now.

I like it quite a bit. Here are some thoughts:

  * The mode documentation really needs to walk the user through how to
setup a custom set of folders.

  * It's not opening my "to-me" folder for some reason. (I thought it
was the '-' at first, but "xorg-board" is working fine). I can debug
this later.

  * The presentation is impressively spartan[*]. :-)

If we spruce this up a bit, I think we'll want to make this the default
view of "M-x notmuch".

Oh, and instead of just documenting how to set a variable in .emacs we
should just provide commands to add/remove folders.

> One missing piece here is that the searches don't have a
> total/unread count. Because the 'notmuch count' command is so fast
> (notmuch count the returns 532891 on my machine, and takes 0.240
> seconds), we really could count the number of messages matching a single
> tag and then *also* count the number of messages matching that tag and
> the inbox tag.

I think the number of threads matching the search is the only
interesting number actually. Otherwise, you just end up printing a bunch
of big numbers that the user doesn't need for anything.

> Another missing piece is that these should be shared with the
> notmuch-poll script, probably via the .notmuch-config file. I do like
> that I can have some entries here that aren't in my notmuch-poll script.

Yes, once we add configuration for automated tagging, we'll want to
figure out how to include those here. I'm not sure if they should just
be an initial default that the user tweaks, or if any configured rules
from that file should always be presented until the user explicitly asks
for one to be ignored (think about a "spam" tag). So that might take
some experimentation.

You're definitely right that we want to support searches other than
simply the tag names in the configuration file. For example, here's the
search I'm currently using for the "notmuch" folder (so I can process
outstanding patches in order):

tag:notmuch and (tag:inbox or tag:todo)

Though, really, I probably wouldn't mind using a search string like that
for any of my automated tags. It's equivalent to what you were doing if
there are no "todo" tags on messages with the tag of interest, and then
as soon as there are any "todo" tags on any of those messages, then I
probably do want them in that folder.

So maybe the user configures a search template to use for each automatic
tag or so?

> It might be nice to make this hierarchical as I used to do with
> evolution's vfolder stuff -- an 'intel' folder with an 'intel/unread'
> sub-folder. That would be done with simple conjunctions of tags, but
> providing some structure on the screen might be nice.
> 
> I'm also wondering if we should elide, or at least change the appearance,
> of lines which match zero messages.

Two nice ideas.

> I'd also like to be able to get the system to display my mail in three
> panes -- one with the index, one with the current search and the last
> with the current thread. Getting those laid out on the screen correctly
> and letting you get them back to that layout easily would make notmuch
> look a lot more like other email clients, a form I've found fairly
> functional as I do not generally read mail in a linear fashion.

Yes. Emacs has pretty good support for saving and restoring an entire
window configuration, so we should be able to make this work.

And by the way, lest you be misled by the "magic space bar", I don't
read my mail very linearly either. I always filter by at least one tag
first and I want to prioritize which one. The folder mode is great for
this. It's only when I get my search results down below a particular
threshold that I decide I want to read everything linearly.

(And if I can't get a particular folder down that small, then I'll do
selective reading (with 'x', yes, I think we're agreeing on that now),
and then archive away the lot.)

Anyway, thanks for the great addition to notmuch.

-Carl

[*] A nice thing about this is it give us plenty of room to have a
paragraph or two explaining how notmuch works, what the user can expect,
what keys to use, etc.


[notmuch] [PATCH] ANSI escapes in "new" only when output is a tty

2009-11-23 Thread Carl Worth
On Mon, 23 Nov 2009 01:54:35 +0100, Adrian Perez  wrote:
> When running "notmuch new --verbose", ANSI escapes are used. This may not be
> desirable when the output of the command is *not* being sent to a terminal
> (e.g. when piping output into another command). In that case each file
> processed is printed in a new line and ANSI escapes are not used at
> all.

I've pushed this now.

And I've noticed two things with it:

1. The filenames are often quite long, and if longer than my terminal
width, then I get one line per output rather than one line continually
erased and reprinted. Any good idea about how to fix that without going
too crazy?

2. On any run after the first, the output says "1/0", "2/0", etc.
So we should fix that to either not print the "/0" when total_messages
is 0 *or* we can just make "notmuch new" unconditionally count the
number of files to be processed, (which I've been thinking I wanted to
do anyway).

I'm trying to eliminate any remaining differences between "notmuch new"
on an initial run and "notmuch new" run later. An important reason to
eliminate these differences is that we want to support the user
interrupting the initial database build and then starting it up again
without losing anything.

Besides the file counting, (which would only make such a user lose the
countdown timer on the subsequent runs), the only other thing we have
different about the first run is that it doesn't ignore read-only
directories. And that one's a problem because it means that if someone
(like me) that has a bunch of read-only directories does the following:

  notmuch dump notmuch.dump
  rm -rf ~/mail/notmuch
  notmuch new # then interrupt this with control-C
  notmuch new # oops! This missed most of my mail
  notmuch restore notmuch.dump

Things go badly wrong here as any mail in read-only directories that
didn't get picked up in the first "notmuch new" run will forever more be
ignored by notmuch new.

So that's totally broken and we should come up with a way to fix it.

-Carl


[notmuch] [PATCH] Support for printing file paths in new command

2009-11-23 Thread Carl Worth
On Mon, 23 Nov 2009 01:53:39 +0100, Adrian Perez de Castro  wrote:
> IMHO it would be nice to have the messages-per-second information as
> well in verbose mode before making it the default. I think I could cook
> up a patch for that, but printing messages-per-second would mean calling
> gettimeofday() for each processed file. Do you think that will be
> acceptable from a performance POV? (Of course using silent mode would
> still only call it once per second).

Or how about using the existing timer to cause a rate to be printed
between the message output once per second?

-Carl


[notmuch] [PATCH 3/3] change config file location to be ~/.notmuch/config

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 18:14:20 -0500, Jameson Graef Rollins  wrote:
> I think Carl said he wanted to keep the ability to specify exactly
> where the database is stored, so if we could move away from something
> that makes any implicit assumptions about relative paths between the
> database and the maildir, then all should be ok.

Well, I chose the relative-path assumptions intentionally. The idea is
that if I move my mail from ~/Mail to ~/mail then the .notmuch directory
moves with it and everything continues to work just fine.

Compare the way .git works and the database stays with the source files
compared to the way cvs works, (where I always seemed to end up with
source files disconnected from the database).

So I might need more convincing to move the database away from the mail.

-Carl


[notmuch] Catching up unread messages

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 22:48:52 +0100, Tassilo Horn  
wrote:
> I got notmuch running, and it's absolutely incredible.  It's so damn
> fast and the results are very good.  So thanks a lot for creating this
> nice piece of software. :-)

Fantastic, Tassilo. I'm glad you got things working and are happy with
the results. And you're quite welcome. I'm just glad I'm able to share
something that has been really useful for me.

> Ok, so new the question: I indexed all my 63.000 mails, and because it
> was a first-time indexing, all my mail now has the tags inbox and
> unread.  Of course, I don't want to SPC through all threads (using the
> great emacs interface) to remove the unread status.  So is there some
> catchup command, which marks all messages in the buffer as read?

If you were to look at the notmuch/TODO file right now, you would see as
the first lines:

Fix the things that are causing the most pain to new users
--
1. A new import is tagging all messages as "inbox" -- total pain

So yes, I understand that this is not useful behavior!

Also, the pain is amplified because the command to *remove* these tags
is currently very slow. So there's some work we need to do before the
initial experience with notmuch is really pleasant for a lot of people.

> BTW, what's the intention of the inbox tag?  When I've read a thread,
> both inbox as well as unread disappear, so I don't get the difference
> between them.

If you get half-way through reading a thread, and then exit, then when
you come back to that thread, notmuch will start you out at the first
unread message in the thread, (and all the read messages will be
collapsed).

Also I often end up archiving entire threads without reading them,
(often for mailing lists that I don't read closely, but just skim the
subject lines once a day or so). For cases like this, I think it's
useful to be able to say things like:

I almost never read this list in its entirety, but I want to
find that message I actually did read recently:

notmuch search tag:lkml and tag:read

Another thing that I think is a little bit useful is if someone points
me to a specific message, it's nice to be able to see "unread" and say
"Oh, yeah, I don't think I ever read that at all."

So that's the idea anyway, (and thanks to sup for showing us the way
here).

-Carl


[notmuch] [RFC] Precedence of OR and AND

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 22:43:30 +0100, Jed Brown  wrote:
> On Sun, 22 Nov 2009 16:36:49 -0500, Bart Trojanowski  
> wrote:
> Absolutely, and I have this applied locally to notmuch.el,

Patch please?

>but I didn't
> fix notmuch-search-filter-by-tag because that would really need to parse
> the expression.

I don't see the difference here. Any time we append to the search
string, we should be doing so with parentheses.

>  I'm just asking if anyone else thinks binding OR
> tighter than AND would be desirable.

Right now, Xapian is doing all of our query parsing. So we'd have to
take things up there to get anything changed for now.

In the future we might be forced into writing our own query parser to
get all the functionality we want.

-Carl


[notmuch] [PATCH] Add install target for desktop files.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 15:17:11 -0600, "Jeffrey C. Ollie"  
wrote:
> Add an install target that uses desktop-file-install to install the
> desktop file in the appropriate location.  The location of the install
> can be modified by changing the desktop_dir variable.

Hi Jeffrey,

I suppose if we're going to have a .desktop file it only makes sense to
install it. A couple of questions:

> +install-desktop:
> + install -d $(DESTDIR)$(desktop_dir)
> + desktop-file-install --mode 0644 --dir $(DESTDIR)$(desktop_dir) 
> notmuch.desktop

What does desktop-file-install do for us here? Anything that we couldn't
do with just "install"? I'm just wanting to be careful that we don't
break "make install" for people who may not even want this file.

If we really do need to install it with desktop-file-install, we could
do a configure check for that program, of course.

Thanks,

-Carl


[notmuch] How to index /var/spool/mail with notmuch

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 21:24:47 +0100, Tassilo Horn  
wrote:
> But I get some permission problems when trying to index /var/spool/mail.
> I was able to create a .notmuch/ directory in there with permissions set
> to 700 for my user.  All mail files are readable for my user.
> 
> Unfortunately, there are some dovecot internal files, which should
> neither be indexed by notmuch, and which have 600 permissions for the
> mail user.  And that's where notmuch errors and stops indexing. :-(

Hi Tassilo, welcome to notmuch!

I'm glad you found a workaround for this problem, (thanks Jed!).

But perhaps these errors should be made into warnings instead? Any
thoughts on that anyone?

> All "real" mail files are named "u.", so it would be cool if I
> could provide a pattern to notmuch matching all files I'd like to index.
> And maybe the other way round (a blacklist pattern) would be useful,
> too.

I've been planning on having a blacklist pattern for a
while. Originally, the only difficulty in implementing it was that we
had nowhere to store configuration information. But we have a
configuration file now, so this would be a pretty easy thing to
implement.

It's not as obvious that a whitelist pattern would be as widely useful,
but it would be possible too.

-Carl


[notmuch] [PATCH] New function notmuch-search-operate-all: operate on all messages in the current query.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 21:12:16 +0100, Jed Brown  wrote:
> It is often convenient to change tags on several messages at once.  This
> function applies any number of tag whitespace-delimited tag
> modifications to all messages matching the current query.
> 
> I have bound this to `*'.

Very nice, Jed!

I've been wanting this feature for a while, and I think you just
improved on my idea in at least two ways.

First I was imagining that the '*' would be a prefix command, but I like
it just prompting for the '+' or '-' as part of the argument. That's no
more typing and allows for doing multiple tags at once.

Second, I like that you just used the search string again, (as opposed
to just walking through the buffer looking at thread IDs). That seems
elegant.

On second thought, however, using the search string is problematic for
at least two reasons:

First, this creates a race condition in that the user will rightly
expect to only be adding/removing tags from the visible results. But if
new mail has been incorporated between creating the current view and
running '*' then threads could be tagged that were never seen and that
could be problematic.

Second, since we're in the search view which shows threads, we should
really be operating on threads. But this tag command won't work like the
'+' and '-' commands in this buffer. Those commands will add/remove a
tag to/from every message in the thread[*]. The new '*' command, however
will only be changing tags on messages that match the query.

So I think we should fix both of these issues by looping over each line
of the buffer and calling (notmuch-search-add-tag) or
(notmuch-search-remove-tag).

What do you think?

-Carl

[*] These existing '+' and '-' operations (as well as 'a') that act on
the entire thread also have a race condition. They are potentially
modifying more messages than the original search matched. This is often
harmless, (you aren't even *seeing* the messages so how can you complain
if more get modified than were there when you did the search.). But it
can actually be fatal:

Imagine I sent a message to the list, and then in the search view I see
that message appear and it has [1/1] indicating it's the only message in
the thread. I might archive this "knowing" I've read the message
already, but this could actually archive a reply as well that arrived
between when I did the search and when I archived.

So that's a bug that we really should fix. [And noted that archiving an
entire thread from the notmuch-show-mode does not have this bug since it
acts only on the explicit messages that are presented.] One option to
fix this would be for "notmuch search" to list all the message IDs that
matched in place of the thread ID (for notmuch-search-mode to hide away
like it does with the thread ID currently). But that seems like it might
get problematic with some hugely long threads.

Anyway, I'm interested in ideas for what we could do here.

Oh, here's one: We could add something like "notmuch tag --expecting=
1/23 " that would not do the tag unless the search string
matched 1 message out of 23 total messages in the thread. Then we could
give a warning to the user. That works for the single-thread case, but
the warning would be harder for the user to deal with in the '*'
case. Or maybe not---the emacs function could just stop on the first
line with the error and then the user would see what's going on.

And we could take a prefix argument to ignore such errors.

Any other thoughts on this?


[notmuch] [RFC PATCH -V2] notmuch: Add support for multiple maildirs

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 23:58:46 +0530, "Aneesh Kumar K.V"  wrote:
> This patch separate database path and maildir paths.
> It also adds support for multiple maildir paths which
> is represented by comma separated values.

I have a running joke with my good friend Behdad that we should add a
git-hook to refuse any commit with the word "also" in the commit
message. It's often a sign that the commit is actually doing two
independent things, and that those two independent things should be
split into separate commits.

I think that's the case here.

> You need to have in ~/.notmuch-config
> [maildirs]
> path=path1,path2

Documentation in the commit message doesn't count. We need this
documentation to be inserted into the configuration file as a comment,
like with the other values.

> +  dirs = g_key_file_get_string (config->key_file,
> +  "maildirs", "path", NULL);
> + if (dirs) {
> + size = sizeof(struct count_ele) + strlen(dirs) + 1;
> + /* comma separated paths */
> + maildirs = (struct count_ele *)malloc(size);

There's a g_key_file_get_string_list function that will do all the
splitting of a multiple-valued configuration entry into multiple
strings. I suggest using that here instead of doing open-coded parsing.

> -prompt ("Top-level directory of your email archive [%s]: ",
> +prompt ("Directory for notmuch database [%s]: ",

Is there really a reason to prompt for this here, rather than just using
a default value (and letting the user know what it is?). One thing I'm
worried about is the user thinking they can run "notmuch setup", change
this value, and expect things to work, (which of course, they won't).

I'd be happier if the user understood that the database is relocatable
and they can just "mv" things around as they want to.

Of course, for that, then we'd actually need to *make* the database
relocatable. One thing that we get right now with the .notmuch directory
_inside_ the mail directory is that everything is relocatable.

If you just pull it out, like you do here, then suddenly the database
will be full of absolute paths to mail files, and things will break if
the top-level mail-directory is moved. And that's a regression compared
to the current case.

> +prompt ("Comma separated maildirs [%s]: ", cmaildirs);

If we are going to support multiple directories for mail here, then we
should prompt separately for each (like we are doing for the email
addresses already).

Also, I'd prefer something like "Top-level directory of email archive"
like we had before. I certainly don't want to give the user the
impression that they need to type in a path to each individual maildir
that they have.

Finally, (and maybe I should have started with this), what's the actual
use case here? Is it difficult to just arrange all mail to be under one
top-level directory, (perhaps just using symlinks even).

-Carl


[notmuch] [PATCH] fix notmuch-new bug when database path ends with a trailing /

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 11:19:31 -0500, Bart Trojanowski  wrote:
> The actual bug was in the filename normalization for storage in the
> database.  The database.path was removed from the full filename, but if
> the database.path from the config file contained a trailing /, the
> relative file name would retain an extra leading /... which made it look
> like an absolute path after it was read out from the DB.

Thanks for the fix, Bart! I've pushed this out now.

-Carl


[notmuch] 25 minutes load time with emacs -f notmuch

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 10:15:39 -0500, Brett Viren  
wrote:
> On Sun, Nov 22, 2009 at 3:36 AM, Mike Hommey  
> wrote:
> But, here is one that looks I/O bound:
> 
>  notmuch tag -unread tag:inbox
> 
> I have my home directory on an encfs volume and I see it and notmuch
> competing for CPU when viewing "top".

Yes. The "notmuch tag" command currently does much more IO than it
really should.

This is Xapian bug 250. Please see:

id:874oon4pgv.fsf at yoom.home.cworth.org 

for some details and thoughts on the bug from me and some pointers on
how one could go about fixing it.

-Carl


[notmuch] [PATCH] fix compiler warnings

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 17:11:03 +0200, Dirk-Jan C. Binnema  wrote:
> 
> (hopefully this is the correct way to send patches...)

Looks just fine, and welcome to notmuch!

> With these minor changes, notmuch compiles warning-free with gcc 4.4.1

Could you resend these as separate patches, each patch fixing a single
type of warning? That would make it more clear what the code is doing.

> -write(2, msg, sizeof(msg)-1);
> +if (write(2, msg, sizeof(msg)-1) < 0) {
> + /* ignore...*/
> +}

I don't like the gratuitous conditional here. It clutters the code and
make is less clear. If we're just trying to squelch a warning about an
unused return value from a function, then I think I'd rather see:

ssize_t ignored;

ignored = write (2, msg, sizeof (msg) - 1);

What do you think?

-Carl


[notmuch] [PATCH] Add SCons build files.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 07:47:10 -0600, "Jeffrey C. Ollie"  
wrote:
> The SCons build files included here *should* do everything that the
> current Makefiles do, plus a little bit of configuration checking.  To
> build/install:

Hi Jeffrey,

Thanks for your effort to code all this up.

But I'm afraid I really don't want to switch away from just using (GNU)
make for the actual compilation.

I don't know anything about scons, but if you can use it to write a
python script that just does the configuration step, (outputting a
Makefile.config say), then that might be very interesting. Some people
have recently told me that python would be a much more sane language for
doing configuration in than shell.

I don't know if they're right or not, but I'm (somewhat) willing to have
multiple implementations of the configure script (since there's always
the option to just skip it and configure Makefile.config manually). But
I'm definitely not willing to have multiple build systems.

> Yes, I'm sure that make is widely available, but as notmuch gets used
> on a wider variety of systems some sort of configuration system will
> become necessary.  If I can prevent another project from going down
> the autoconf/automake path I'll be happy.  I started creating CMake
> build files but I don't know CMake well enough to come up with a
> working build.

I'm totally glad to try to avoid autoconf/automake. I know for sure that
I never want to use libtool again, (I've learned that the hard way). I
don't have as much prejudice against automake, but I've heard a rumor
that it's hard to make it *not* use libtool.

Meanwhile, the only advantage I know for automake is that once it's
setup, adding a new file to compile is as simple as adding one file to a
list in the Makefile.am. We've already got notmuch as easy as that with
just adding a file to a list in Makefile.local.

So then all that's left is a configuration system. The notion of how the
final "configure" script from autoconf works seems just fine to me, but
I'm not sure the implementation of autoconf itself is sound. I've been
maintaining a project for years (cairo) where the m4-complexity in
configure.ac has far outgrown my ability to understand it. And I'm
extremely uncomfortable with a build system I can't understand.

Meanwhile, cairo *still* has a shell script needed just to bootstrap the
autconf/automake/libtool house of cards, and that shell script alone is
194 lines.

So I'd very much like to continue exploring what we can do with our own
configuration system, (in whatever language/language(s) make sense). In
the meantime, I'm happy that I can just checkout and build notmuch on a
Linux system with no configure step at all. I also like that the
build-system doesn't trigger constant re-runs of configure all the
time. I've spent too many days of my life watching autoconf output
scroll by, and I'd really like to avoid going down that road.

So yes, Jeffrey, if avoiding autoconf is the motivation, then I'm right
there with you. But I'm not convinced that throwing out GNU make is the
right thing to do as well.

Thanks for listening,

-Carl


[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 15:32:13 -0800, Keith Packard  wrote:
> That's a fine plan. It 'shouldn't' be too hard to implement either.

Noted in TODO for future reference.

> Btw, I'm thinking that it might be useful to create some 'global'
> notmuch keybindings and then create per-view bindings that also expose
> the global bindings. That way, things like 'm' to create a new mail
> would work consistently in each view. Note that this idea is
> inconsistent with the following though...

That's an excellent idea. And it's consistent with what I want 'a' to
do, (and I do think it's important to have these commands consistent
across the views). I think it's natural too. See below...

> I was trying to make the 'normal' action easier; for me, if I'm looking
> at a message, then the normal action is to mark it read and archived,
> but when I'm looking only at the subject line in the search window, the
> normal action is just to mark it archived (having not actually read the
> message).

I agree that "normal" should be easier too. So I just need to win you
over to my notion of "normal", (and teach you of the ways of the magic
space bar).

The most normal thing (for me) to do *when at the end of a thread* is
to mark it read, archive it, and then advance to the next message. And
that's exactly what space bar does.

If you're not at the end of a thread, then you can archive it, (that's
what 'a' is for), but it shouldn't be marked read, (because otherwise
that would be "cheating").[*]

And if you want to cheat willingly, (notmuch, please consider these
messages read even though you've never presented them to me), then
that should require an extra-explicit action. So that's the shift key.

[*] We should perhaps fix 'a' to remove the "unread" tag from any
messages that _are_ wholly visible in the current window. It's really
only when an entire thread fits this one, and I *did* read it, that I
end up reaching for the 'A' binding.

So does that make sense?

The question of whether you next want to see the next message, or you
would rather return to the search view, is a trickier one. I'd suggest
that there's no harm in seeing the next message after archiving the
current message, from which you can immediately return to the search
view with 'q' (or 'x' currently, but not with your patch). That does
mean that "archive and return to search" does require two keys instead
of one.

Hmm... if we fix 'a' to correctly remove "unread" from wholly
presented messages, then I wouldn't need the current 'A' keybinding at
all. That is, notmuch would be automatically managing "unread" tags in
a fairly consistent way, and we wouldn't be giving UI for the
"cheating", (which should be fine---I can't see a good reason for
cheating here).

If we did that, then we could make 'a' do archive-go-to-next-message
and 'A' do archive-return-to-search-view. What would you think about
that?

-Carl
Date: Mon, 23 Nov 2009 04:02:59 +0100
Message-ID: <871vjqgcyk.fsf at yoom.home.cworth.org>


[notmuch] [PATCH] makefile: Tell echo to interpret escape sequences.

2009-11-23 Thread Jan Janak
On Mon, Nov 23, 2009 at 3:41 AM, Carl Worth  wrote:
> On Sun, 22 Nov 2009 13:44:37 +0100, Jan Janak  wrote:
>> The initial message that informs the user about the possibility to use
>> make V=1 contains a \n at the end, but echo wouldn't interpret that
>> properly without the -e command line option.
>
> Patch doesn't work for me.
>
> Before patch:
>
> ? ? ? ?0:~/src/notmuch:(master)$ make
> ? ? ? ?Use "make V=1" to see the verbose compile lines.
> ? ? ? ? ?CC ? ?notmuch-new.o
> ? ? ? ? ?CXX ? notmuch
>
> After patch:
>
> ? ? ? ?0:~/src/notmuch:(master)$ make
> ? ? ? ?-e Use "make V=1" to see the verbose compile lines.
> ? ? ? ? ?CC ? ?debugger.o
> ? ? ? ?-e ? CC gmime-filter-reply.o
> ? ? ? ?-e ? CC notmuch.o
>
> It's a shame that simple things like "echo" aren't easy to use portably.
> (And yes, I know that autoconf has a bunch of tests for echo, such as
> how to get the behavior of "echo -n", etc.)

It seems your echo interprets escape sequences by default. When I run
make, the first line of output looks like this:

Use "make V=1" to see the verbose compile lines.\n  CC  debugger.o
  CCgmime-filter-reply.o
  CCnotmuch.o

This is on Debian Lenny. Anyway, this one is not important either.

  -- Jan


[notmuch] [PATCH] makefile: Declare clean target as phony.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 13:55:35 +0100, Jan Janak  wrote:
> This ensures that make clean always proceeds, even if the user
> accidentally creates a file named 'clean'. Also, it ignores errors in
> rm and other commands.

Now *this* patch worked fine for me. Thanks! I've pushed it now.

-Carl


[notmuch] [PATCH] notmuch-new: Eliminate gcc warning caused by ino_cmp.

2009-11-23 Thread Jan Janak
On Mon, Nov 23, 2009 at 3:38 AM, Carl Worth  wrote:
> On Sun, 22 Nov 2009 13:32:36 +0100, Jan Janak  wrote:
>> The function passed to scandir in the fourth argument takes two
>> const void* arguments. To eliminate the gcc warning about incompatible
>> types, we change ino_cmp to match this and then re-type the parameters
>> in the body of ino_cmp.
>
> Actually, on my system at least, (Linux with glibc 2.10.1), our current
> function matches the prototype. So applying your patch actually
> *introduces* a warning where there was no warning before.
>
> What a nuisance...
>
> Any ideas for a good fix, anyone?

OK, I have an older version of glibc. If the original code works with
glibc 2.10 then just ignore the patch. I think testing for a
particular version of glibc is not worth the effort (it's just a
warning anyway).

  -- Jan


[notmuch] [PATCH] makefile: Tell echo to interpret escape sequences.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 13:44:37 +0100, Jan Janak  wrote:
> The initial message that informs the user about the possibility to use
> make V=1 contains a \n at the end, but echo wouldn't interpret that
> properly without the -e command line option.

Patch doesn't work for me.

Before patch:

0:~/src/notmuch:(master)$ make
Use "make V=1" to see the verbose compile lines.
  CCnotmuch-new.o
  CXX   notmuch

After patch:

0:~/src/notmuch:(master)$ make 
-e Use "make V=1" to see the verbose compile lines.
  CCdebugger.o
-e   CC gmime-filter-reply.o
-e   CC notmuch.o

It's a shame that simple things like "echo" aren't easy to use portably.
(And yes, I know that autoconf has a bunch of tests for echo, such as
how to get the behavior of "echo -n", etc.)

-Carl


[notmuch] [PATCH] notmuch-new: Eliminate gcc warning caused by ino_cmp.

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 13:32:36 +0100, Jan Janak  wrote:
> The function passed to scandir in the fourth argument takes two
> const void* arguments. To eliminate the gcc warning about incompatible
> types, we change ino_cmp to match this and then re-type the parameters
> in the body of ino_cmp.

Actually, on my system at least, (Linux with glibc 2.10.1), our current
function matches the prototype. So applying your patch actually
*introduces* a warning where there was no warning before.

What a nuisance...

Any ideas for a good fix, anyone?

-Carl


[notmuch] [PATCH] Support multiple configuration files via $NOTMUCH_CONFIG

2009-11-23 Thread Carl Worth
On Sat, 21 Nov 2009 23:18:26 -0600, Alec Berryman  wrote:
> If present, $NOTMUCH_CONFIG will be used as the configuration file
> location.

Hi Alec, welcome to notmuch!

And thanks for this patch. I've pushed it now.

I need this quite often when setting up a new database for testing a
patch, for example. And I had an environment variable for the database
path once upon a time, before adding a configuration file. But I lost
that feature when adding the configuration file. So it's really nice to
have this functionality back again.

We should probably add support for "notmuch -f " as
well. I've noted that idea in the TODO file now, (which just keeps
growing somehow).

-Carl


[notmuch] Guide for new users?

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 18:02:36 +0100, Jed Brown  wrote:
> Yes, however it will change flags which changes file names and currently
> confuses notmuch.  I synced [Gmail].All Mail with OfflineIMAP and am now
> using Getmail to pull via POP.  In the Gmail settings, activate POP
> starting at the current time.  I'll switch back to OfflineIMAP when
> notmuch is happy with changing file names.

Coming soon! I've been told the patch has been sent to the list already.

> The following should save notmuch + Gmail users some time.

Hey, that's a great document. We really need a nice wiki for
notmuchmail.org already. (And when I say "wiki" I think I really mean
something with email-based submission of some sort.)

I suppose that with ikiwiki I could easily write a script to accept an
email on stdin and make a git commit out of it. So then I could just
pipe useful messages straight from my inbox to the wiki. I think that's
what I'll do. (For now, I'll tag that message as notmuch-wiki so I will
be able to easily find it later.)

Another thing I'd really like would be a notmuch-based interface to our
mailing list archives. Then I would tag the previous message as "howto",
"gmail", "getmail", and "offlineimap".

Anyway, thanks for sharing this!

-Carl


[notmuch] Guide for new users?

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 12:44:17 +0800, Jjgod Jiang  wrote:
> I think it will be nice if we can have a guide/tutorial like
> documentation for new users. For myself, I have the following
> questions (I am an alpine user previously, so some of the
> questions are not related to notmuch directly):

Hi Jiang, welcome to notmuch!

There's definitely a lot more documentation we could use. I think one of
the things I'd like to know is, where did you look when you wanted
answers to these questions? That can help us know where the best places
are to put some answers.

As for getting started with notmuch itself, I've tried to make it fairly
self-guided. (That is, if you just run "notmuch"[*] it should keep
telling you what to do next.) I'd be very interested in getting feedback
from people on how well this works. Did you run it that way? Were its
suggestions helpful?

[*] The assumption being that people will try to run the program before
reading any documentation.

> 1. What's the most efficient way to sync mails from my gmail
> account to a local Maildir? I've tried offlineimap but it
> keeps crashing python (!) on my system (python 2.6, Mac OS X
> 10.6.2).

One of the big tricks with switching to notmuch is that there's so much
that notmuch doesn't do. If one is coming from a monolithic email
program (such as evolution) or webmail (such as gmail) then notmuch only
replaces a tiny piece of the mail program, (search and tagging).

But the user also needs replacements for all of the other pieces of the
mail program. Such as:

  * Receiving mail

  * Composing mail (with a nice address book)

  * Sending mail

And likely other stuff I'm not thinking of right now. So those things
can involve lots of different programs. For receiving it might be
offlineimap, getmail, fetchmail, procmail, maildrop or some
combination. For composing it could be emacs, vim, etc. And sending mail
might involve msmtp, postfix, or exim4, etc.

That's a long list of packages, and likely an overwhelming set of
possibilities as well as a ton to learn for setting these up and
configuring them.

So I think you're right that we're going to want some guide suggesting
best practicing for setting things like this up.

> 2. How to add notmuch.el into my .emacsrc?

We've at least added this much to INSTALL now. First do:

sudo make install-emacs

Then in your .emacs add:

(require 'notmuch)

And then you can run "M-x notmuch". 

> I know notmuch feels like a tool for geeks, but it will probably
> lower the barrier if someone can provide such a guide in a
> straightforward, step-by-step way.

A "tool for geeks" means that it works well and efficiently, (without
"fluff" or mis-features). It doesn't mean that it needs to be hard to
learn, or require specialized knowledge in advance before using it.

So yes, I totally agree that we need to document things like this
better, and make it as easy to start using notmuch as possible.

-Carl


[notmuch] [PATCH] Mac OS X compatibility fixes

2009-11-23 Thread Carl Worth
On Sun, 22 Nov 2009 12:31:53 +0800, Jjgod Jiang  wrote:
> On Sun, Nov 22, 2009 at 12:17 PM, Alexander Botero-Lowry
> 
> The problem is that notmuch does not have a fully functional configure
> process yet, Carl did mention Makefile.local, but it seems this file is
> not generated by configure right now. (No config.h either.)

We do now have Makefile.config being generated, (and we can move to
config.h to avoid the overly-long command-line problem if necessary).

> I will be happy to fix my patch if such facility (like
> AC_CHECK_FUNCS([getline])) exists.

Chris, do you want to tackle this one? ;-)

A really easy hack would be to detect glibc, and if present, use all the
existing code in notmuch. If not present, then use all the compatibility
functions. This could be by building a notmuch-compat.c that defines
functions like _notmuch_strndup() and then adding thins like:

#define strndup _notmuch_strndup.

That would allow our current configure script to stay quite simple. If
people want more sophistication we could write functions in the
configuration script for doing test compiles to find functions, etc.

-Carl


[notmuch] search-tags and tag completion in notmuch.el

2009-11-23 Thread Jan Janak
Hello,

The three patches I sent to the list a couple of minutes ago is another
revision of the patches that I had sent earlier. The first two patches
implement support for 'notmuch search-tags'. The last patch adds support
for tag completion to notmuch.el using the new command.

Right now 'notmuch search-tags' can only list all tags from the
database, it does not support search-terms yet (i.e. it cannot list tags
for a restricted set of messages or threads), but I am working on that
feature and I'm gonna send another patch implementing that soon. I think
sending more smaller incremental patches makes it easier to review them
(and for me personally it is easier to keep them up-to-date on top of
moving Carl's git repository).

I considered implementing 'notmuch search --output=tags' (as we
discussed in another email), but it turned out that:

  * Having 'notmuch search-tags' would be consistent with Carl's
'notmuch search-messages'.

  * 'notmuch search' supports other command line options (--first,
--max-threads, --sort) and these would only work when the user uses
the command to search for messages. They would probably be useless
if we use the command to search for tags and messages (well, at
least some of them). Which means we would have to let the user know
in the documentation, or disable some of them based on the value of
the --output command line parameter, etc etc...

  * 'notmuch search-tags' is easier on fingers than 
'notmuch search --output=tags' :-).

In any case, we should probably keep it consistent with other commands
and because Carl submitted 'notmuch search-messages", I did the same for
tags.

I'd personally prefer to use different commands for different kinds of
output rather than overloading 'notmuch search' with more command line
options, but it's just a personal preference. I can change the patch
again if we decide that we're going to overload 'notmuch search' rather
than add more commands.

Comments, ideas, and suggestions are welcome!

  -- Jan


[notmuch] [PATCH] ANSI escapes in "new" only when output is a tty

2009-11-23 Thread Adrian Perez
When running "notmuch new --verbose", ANSI escapes are used. This may not be
desirable when the output of the command is *not* being sent to a terminal
(e.g. when piping output into another command). In that case each file
processed is printed in a new line and ANSI escapes are not used at all.
---
 notmuch-client.h |1 +
 notmuch-new.c|   12 
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index f105c8b..4fe182e 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -74,6 +74,7 @@ typedef void (*add_files_callback_t) (notmuch_message_t 
*message);
 typedef struct {
 int ignore_read_only_directories;
 int saw_read_only_directory;
+int output_is_a_tty;
 int verbose;

 int total_files;
diff --git a/notmuch-new.c b/notmuch-new.c
index a2b30bd..8172b49 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -180,10 +180,15 @@ add_files_recursive (notmuch_database_t *notmuch,
state->processed_files++;

if (state->verbose) {
-   printf ("\r\033[K%i/%i: %s\r",
+   if (state->output_is_a_tty)
+   printf("\r\033[K");
+
+   printf ("%i/%i: %s",
state->processed_files,
state->total_files,
next);
+
+   putchar((state->output_is_a_tty) ? '\r' : '\n');
fflush (stdout);
}

@@ -282,9 +287,7 @@ add_files (notmuch_database_t *notmuch,
return NOTMUCH_STATUS_FILE_ERROR;
 }

-if (isatty (fileno (stdout)) && ! debugger_is_active ()
-   && ! state->verbose)
-{
+if (state->output_is_a_tty && ! debugger_is_active () && ! state->verbose) 
{
/* Setup our handler for SIGALRM */
memset (, 0, sizeof (struct sigaction));
action.sa_handler = handle_sigalrm;
@@ -405,6 +408,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
 int i;

 add_files_state.verbose = 0;
+add_files_state.output_is_a_tty = isatty (fileno (stdout));

 for (i = 0; i < argc && argv[i][0] == '-'; i++) {
if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) {
-- 
1.6.5.2



[notmuch] [PATCH] Support for printing file paths in new command

2009-11-23 Thread Adrian Perez de Castro
On Mon, 23 Nov 2009 01:24:09 +0100, Carl wrote:

> On Sat, 21 Nov 2009 01:17:18 +0100, Adrian Perez  wrote:
> > For very large mail boxes, it is desirable to know which files are being
> > processed e.g. when a crash occurs to know which one was the cause. Also,
> > it may be interesting to have a better idea of how the operation is
> > progressing when processing mailboxes with big messages.
> > 
> > This patch adds support for printing messages as they are processed by
> > "notmuch new":
> 
> Hey, that's pretty nice.

Thanks!

As a small improvement, I will send another patch in a while, which will
avoid sending ANSI escapes when output is not a terminal, and print one
file path per line in that case.

> I've pushed this now, (and I'm almost tempted to make it the
> default...).

IMHO it would be nice to have the messages-per-second information as
well in verbose mode before making it the default. I think I could cook
up a patch for that, but printing messages-per-second would mean calling
gettimeofday() for each processed file. Do you think that will be
acceptable from a performance POV? (Of course using silent mode would
still only call it once per second).

Regards,

-- 
Adrian Perez de Castro 
Igalia - Free Software Engineering
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20091123/aba0f79c/attachment.pgp>


[notmuch] [PATCH] Insert signature into replies

2009-11-23 Thread Carl Worth
On Fri, 20 Nov 2009 20:57:35 -0800, Keith Packard  wrote:
> When you compose a new message, message mode carefully inserts your
> mail signature at the bottom of the message; as notmuch constructs the
> reply all by itself, this doesn't happen then. Use the message mode
> function 'message-insert-signature' to add that to reply buffers.

Very nice. And look below! It works too. :-)

Pushed

-Carl
-- 
Searching for an email solution? There's not much out there.
http://notmuchmail.org


[notmuch] [PATCH] Quote file names passed to the shell

2009-11-23 Thread Carl Worth
On Sat, 21 Nov 2009 03:37:54 +0100, Jed Brown  wrote:
> Prior to this, notmuch-show-pipe-message could not handle file names
> with spaces and similar.

Thanks for the fix, Jed. This is pushed.

-Carl


[notmuch] [PATCH] Support for printing file paths in new command

2009-11-23 Thread Carl Worth
On Sat, 21 Nov 2009 01:17:18 +0100, Adrian Perez  wrote:
> For very large mail boxes, it is desirable to know which files are being
> processed e.g. when a crash occurs to know which one was the cause. Also,
> it may be interesting to have a better idea of how the operation is
> progressing when processing mailboxes with big messages.
> 
> This patch adds support for printing messages as they are processed by
> "notmuch new":

Hey, that's pretty nice.

I've pushed this now, (and I'm almost tempted to make it the
default...).

-Carl


[notmuch] [PATCH 3/3] notmuch.el: Select tag names with completion.

2009-11-23 Thread Jan Janak
Several commands ask the user for a tag name. With this feature the
user can just press tab and Emacs automatically retrieves the list of
all existing tags from notmuch database with 'notmuch search-tags' and
presents a completion buffer to the user.

This feature is very useful for users who have a large number of tags
because it saves typing and minimizes the risk of typos.

Signed-off-by: Jan Janak 
---
 notmuch.el |   22 +-
 1 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/notmuch.el b/notmuch.el
index 5927737..b6be395 100644
--- a/notmuch.el
+++ b/notmuch.el
@@ -139,6 +139,13 @@ within the current window."
   (or (memq prop buffer-invisibility-spec)
  (assq prop buffer-invisibility-spec)

+(defun notmuch-select-tag-with-completion (prompt)
+  (let ((tag-list
+(with-output-to-string
+  (with-current-buffer standard-output
+(call-process notmuch-command nil t nil "search-tags")
+(completing-read prompt (split-string tag-list "\n+" t) nil nil nil)))
+
 (defun notmuch-show-next-line ()
   "Like builtin `next-line' but ensuring we end on a visible character.

@@ -202,7 +209,8 @@ Unlike builtin `next-line' this version accepts no 
arguments."

 (defun notmuch-show-add-tag ( toadd)
   "Add a tag to the current message."
-  (interactive "sTag to add: ")
+  (interactive
+   (list (notmuch-select-tag-with-completion "Tag to add: ")))
   (apply 'notmuch-call-notmuch-process
 (append (cons "tag"
   (mapcar (lambda (s) (concat "+" s)) toadd))
@@ -211,7 +219,8 @@ Unlike builtin `next-line' this version accepts no 
arguments."

 (defun notmuch-show-remove-tag ( toremove)
   "Remove a tag from the current message."
-  (interactive "sTag to remove: ")
+  (interactive
+   (list (notmuch-select-tag-with-completion "Tag to remove: ")))
   (let ((tags (notmuch-show-get-tags)))
 (if (intersection tags toremove :test 'string=)
(progn
@@ -970,12 +979,14 @@ and will also appear in a buffer named \"*Notmuch 
errors*\"."
(split-string (buffer-substring beg end))

 (defun notmuch-search-add-tag (tag)
-  (interactive "sTag to add: ")
+  (interactive
+   (list (notmuch-select-tag-with-completion "Tag to add: ")))
   (notmuch-call-notmuch-process "tag" (concat "+" tag) 
(notmuch-search-find-thread-id))
   (notmuch-search-set-tags (delete-dups (sort (cons tag 
(notmuch-search-get-tags)) 'string<

 (defun notmuch-search-remove-tag (tag)
-  (interactive "sTag to remove: ")
+  (interactive
+   (list (notmuch-select-tag-with-completion "Tag to remove: ")))
   (notmuch-call-notmuch-process "tag" (concat "-" tag) 
(notmuch-search-find-thread-id))
   (notmuch-search-set-tags (delete tag (notmuch-search-get-tags

@@ -1061,7 +1072,8 @@ current search results AND the additional query string 
provided."

 Runs a new search matching only messages that match both the
 current search results AND that are tagged with the given tag."
-  (interactive "sFilter by tag: ")
+  (interactive
+   (list (notmuch-select-tag-with-completion "Filter by tag: ")))
   (notmuch-search (concat notmuch-search-query-string " and tag:" tag) 
notmuch-search-oldest-first))

 (defun notmuch ()
-- 
1.6.3.3



[notmuch] [PATCH 2/3] notmuch: New command 'search-tags'.

2009-11-23 Thread Jan Janak
This is a new notmuch command that can be used to search for all tags
found in the database. The resulting list is alphabetically sorted.

The primary use-case for this new command is to provide the tag
completion feature in Emacs (and other interfaces).

Signed-off-by: Jan Janak 
---
 Makefile.local|1 +
 notmuch-client.h  |3 ++
 notmuch-search-tags.c |   71 +
 notmuch.c |6 
 4 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 notmuch-search-tags.c

diff --git a/Makefile.local b/Makefile.local
index 2828659..d8f7906 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -12,6 +12,7 @@ notmuch_client_srcs = \
notmuch-reply.c \
notmuch-restore.c   \
notmuch-search.c\
+   notmuch-search-tags.c   \
notmuch-setup.c \
notmuch-show.c  \
notmuch-tag.c   \
diff --git a/notmuch-client.h b/notmuch-client.h
index ea77686..c6142b5 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -114,6 +114,9 @@ notmuch_show_command (void *ctx, int argc, char *argv[]);
 int
 notmuch_tag_command (void *ctx, int argc, char *argv[]);

+int
+notmuch_search_tags_command (void *ctx, int argc, char *argv[]);
+
 const char *
 notmuch_time_relative_date (const void *ctx, time_t then);

diff --git a/notmuch-search-tags.c b/notmuch-search-tags.c
new file mode 100644
index 000..1201165
--- /dev/null
+++ b/notmuch-search-tags.c
@@ -0,0 +1,71 @@
+/* notmuch - Not much of an email program, (just index and search)
+ *
+ * Copyright ?? 2009 Carl Worth
+ * Copyright ?? 2009 Jan Janak
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/ .
+ *
+ * Author: Jan Janak 
+ */
+
+#include "notmuch-client.h"
+
+static int
+list_all_tags (notmuch_database_t* db)
+{
+notmuch_tags_t* tags;
+const char* t;
+
+if ((tags = notmuch_database_get_all_tags (db)) == NULL) {
+   fprintf (stderr, "Error while obtaining tags from the database.\n");
+   return 1;
+}
+
+while((t = notmuch_tags_get (tags))) {
+   printf ("%s\n", t);
+   notmuch_tags_advance (tags);
+}
+
+notmuch_tags_destroy (tags);
+return 0;
+}
+
+int
+notmuch_search_tags_command (void *ctx, int argc, char *argv[])
+{
+notmuch_config_t *config;
+notmuch_database_t *db;
+
+config = NULL;
+db = NULL;
+
+if ((config = notmuch_config_open (ctx, NULL, NULL)) == NULL) {
+   goto error;
+}
+
+db = notmuch_database_open (notmuch_config_get_database_path (config),
+   NOTMUCH_DATABASE_MODE_READ_ONLY);
+if (db == NULL) {
+   goto error;
+}
+
+if (list_all_tags (db) != 0) goto error;
+
+notmuch_database_close (db);
+return 0;
+
+error:
+if (db) notmuch_database_close (db);
+return 1;
+}
diff --git a/notmuch.c b/notmuch.c
index 5cc8e4c..b1d7cf9 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -230,6 +230,12 @@ command_t commands[] = {
   "\t\tSo if you've previously been using sup for mail, then the\n"
   "\t\t\"notmuch restore\" command provides you a way to import\n"
   "\t\tall of your tags (or labels as sup calls them)." },
+{ "search-tags", notmuch_search_tags_command,
+  NULL,
+  "List all tags found in the database.",
+  "\t\tThis command returns an alphabetically sorted list of all tags\n"
+  "\t\tthat are present in the database. In other words, the resulting\n"
+  "\t\tlist is a collection of all tags from all messages." },
 { "help", notmuch_help_command,
   "[]",
   "\t\tThis message, or more detailed help for the named command.",
-- 
1.6.3.3



[notmuch] [PATCH 1/3] notmuch: New function to retrieve all tags from the database.

2009-11-23 Thread Jan Janak
This patch adds a new function called notmuch_database_get_all_tags
which can be used to obtain a list of all tags from the database
(in other words, the list contains all tags from all messages). The
function produces an alphabetically sorted list.

To add support for the new function, we rip the guts off of
notmuch_message_get_tags and put them in a new generic function
called _notmuch_convert_tags. The generic function takes a
Xapian::TermIterator as argument and uses the iterator to find tags.
This makes the function usable with different Xapian objects.

Function notmuch_message_get_tags is then reimplemented to call the
generic function with message->doc.termlist_begin() as argument.

Similarly, we implement notmuch_message_database_get_all_tags, the
function calls the generic function with db->xapian_db->allterms_begin()
as argument.

Finally, notmuch_database_get_all_tags is exported through
lib/notmuch.h

Signed-off-by: Jan Janak 
---
 lib/database-private.h |   13 +
 lib/database.cc|   43 +++
 lib/message.cc |   34 +++---
 lib/notmuch.h  |   10 ++
 4 files changed, 69 insertions(+), 31 deletions(-)

diff --git a/lib/database-private.h b/lib/database-private.h
index 5f178f3..37f9bf8 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -34,4 +34,17 @@ struct _notmuch_database {
 Xapian::TermGenerator *term_gen;
 };

+/* Convert tags from Xapian internal format to notmuch format.
+ *
+ * The function gets a TermIterator as argument and uses that iterator to find
+ * all tag terms in the object. The tags are then converted to a
+ * notmuch_tags_t list and returned. The function needs to allocate memory for
+ * the resulting list and it uses the argument ctx as talloc context.
+ *
+ * The function returns NULL on failure.
+ */
+notmuch_tags_t *
+_notmuch_convert_tags (void *ctx, Xapian::TermIterator ,
+  Xapian::TermIterator );
+
 #endif
diff --git a/lib/database.cc b/lib/database.cc
index 2c90019..5d2add7 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -1026,3 +1026,46 @@ notmuch_database_add_message (notmuch_database_t 
*notmuch,

 return ret;
 }
+
+notmuch_tags_t *
+_notmuch_convert_tags (void *ctx, Xapian::TermIterator ,
+  Xapian::TermIterator )
+{
+const char *prefix = _find_prefix ("tag");
+notmuch_tags_t *tags;
+std::string tag;
+
+/* Currently this iteration is written with the assumption that
+ * "tag" has a single-character prefix. */
+assert (strlen (prefix) == 1);
+
+tags = _notmuch_tags_create (ctx);
+if (unlikely (tags == NULL))
+   return NULL;
+
+i.skip_to (prefix);
+
+while (i != end) {
+   tag = *i;
+
+   if (tag.empty () || tag[0] != *prefix)
+   break;
+
+   _notmuch_tags_add_tag (tags, tag.c_str () + 1);
+
+   i++;
+}
+
+_notmuch_tags_prepare_iterator (tags);
+
+return tags;
+}
+
+notmuch_tags_t *
+notmuch_database_get_all_tags (notmuch_database_t *db)
+{
+Xapian::TermIterator i, end;
+i = db->xapian_db->allterms_begin();
+end = db->xapian_db->allterms_end();
+return _notmuch_convert_tags(db, i, end);
+}
diff --git a/lib/message.cc b/lib/message.cc
index 017c47b..d27ea92 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -459,38 +459,10 @@ notmuch_message_get_date (notmuch_message_t *message)
 notmuch_tags_t *
 notmuch_message_get_tags (notmuch_message_t *message)
 {
-const char *prefix = _find_prefix ("tag");
 Xapian::TermIterator i, end;
-notmuch_tags_t *tags;
-std::string tag;
-
-/* Currently this iteration is written with the assumption that
- * "tag" has a single-character prefix. */
-assert (strlen (prefix) == 1);
-
-tags = _notmuch_tags_create (message);
-if (unlikely (tags == NULL))
-   return NULL;
-
-i = message->doc.termlist_begin ();
-end = message->doc.termlist_end ();
-
-i.skip_to (prefix);
-
-while (i != end) {
-   tag = *i;
-
-   if (tag.empty () || tag[0] != *prefix)
-   break;
-
-   _notmuch_tags_add_tag (tags, tag.c_str () + 1);
-
-   i++;
-}
-
-_notmuch_tags_prepare_iterator (tags);
-
-return tags;
+i = message->doc.termlist_begin();
+end = message->doc.termlist_end();
+return _notmuch_convert_tags(message, i, end);
 }

 void
diff --git a/lib/notmuch.h b/lib/notmuch.h
index a61cd02..e2f1398 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -280,6 +280,16 @@ notmuch_message_t *
 notmuch_database_find_message (notmuch_database_t *database,
   const char *message_id);

+/* Return a list of all tags found in the database.
+ *
+ * This function creates a list of all tags found in the database. The
+ * resulting list contains all tags from all messages found in the database.
+ *
+ * On error this function returns NULL.
+ */
+notmuch_tags_t *

[notmuch] [PATCH] Support for printing file paths in new command

2009-11-23 Thread Adrian Perez
For very large mail boxes, it is desirable to know which files are being
processed e.g. when a crash occurs to know which one was the cause. Also,
it may be interesting to have a better idea of how the operation is
progressing when processing mailboxes with big messages.

This patch adds support for printing messages as they are processed by
"notmuch new":

* The "new" command now supports a "--verbose" flag.

* When running in verbose mode, the file path of the message about to be
  processed is printed in the following format:

current/total: /path/to/message/file

  Where "current" is the number of messages processed so far and "total" is
  the total count of files to be processed.

* The status line is erased using an ANSI sequence "\033[K" (erase current
  line from the cursor to the end of line) each time it is refreshed. This
  should not pose a problem because nearly every terminal supports it.

* When output is not being sent to a terminal, then each file processed is
  printed in a new line and ANSI escapes are not used at all.

* The signal handler for SIGALRM and the timer are not enabled when running
  in verbose mode, because we are already printing progress with each file,
  periodical reports are not neccessary.
---
 notmuch-client.h |2 ++
 notmuch-new.c|   32 +---
 notmuch.c|   11 +--
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index ea77686..4fe182e 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -74,6 +74,8 @@ typedef void (*add_files_callback_t) (notmuch_message_t 
*message);
 typedef struct {
 int ignore_read_only_directories;
 int saw_read_only_directory;
+int output_is_a_tty;
+int verbose;

 int total_files;
 int processed_files;
diff --git a/notmuch-new.c b/notmuch-new.c
index 0dd2784..b5c6cc6 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -179,6 +179,19 @@ add_files_recursive (notmuch_database_t *notmuch,
if (path_dbtime == 0 || st->st_mtime > path_dbtime) {
state->processed_files++;

+   if (state->verbose) {
+   if (state->output_is_a_tty)
+   printf("\r\033[K");
+
+   printf ("%i/%i: %s",
+   state->processed_files,
+   state->total_files,
+   next);
+
+   putchar((state->output_is_a_tty) ? '\r' : '\n');
+   fflush (stdout);
+   }
+
status = notmuch_database_add_message (notmuch, next, );
switch (status) {
/* success */
@@ -275,7 +288,7 @@ add_files (notmuch_database_t *notmuch,
 }

 /* Setup our handler for SIGALRM */
-if (isatty (fileno (stdout)) && ! debugger_is_active ()) {
+if (state->output_is_a_tty && ! debugger_is_active () && ! state->verbose) 
{
memset (, 0, sizeof (struct sigaction));
action.sa_handler = handle_sigalrm;
sigemptyset (_mask);
@@ -296,6 +309,7 @@ add_files (notmuch_database_t *notmuch,

 /* Now stop the timer. */
 if (timer_is_active) {
+   /* Now stop the timer. */
timerval.it_interval.tv_sec = 0;
timerval.it_interval.tv_usec = 0;
timerval.it_value.tv_sec = 0;
@@ -380,8 +394,7 @@ count_files (const char *path, int *count)
 }

 int
-notmuch_new_command (void *ctx,
-unused (int argc), unused (char *argv[]))
+notmuch_new_command (void *ctx, int argc, char *argv[])
 {
 notmuch_config_t *config;
 notmuch_database_t *notmuch;
@@ -393,6 +406,19 @@ notmuch_new_command (void *ctx,
 const char *db_path;
 char *dot_notmuch_path;
 struct sigaction action;
+int i;
+
+add_files_state.verbose = 0;
+add_files_state.output_is_a_tty = isatty (fileno (stdout));
+
+for (i = 0; i < argc && argv[i][0] == '-'; i++) {
+   if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) {
+   add_files_state.verbose = 1;
+   } else {
+   fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+   return 1;
+   }
+}

 /* Setup our handler for SIGINT */
 memset (, 0, sizeof (struct sigaction));
diff --git a/notmuch.c b/notmuch.c
index 5cc8e4c..8cb1310 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -107,8 +107,8 @@ command_t commands[] = {
   "\t\tInvoking notmuch with no command argument will run setup if\n"
   "\t\tthe setup command has not previously been completed." },
 { "new", notmuch_new_command,
-  NULL,
-  "Find and import new messages to the notmuch database.",
+  "[--verbose]",
+  "\t\tFind and import new messages to the notmuch database.",
   "\t\tScans all sub-directories of the mail directory, performing\n"
   "\t\tfull-text indexing on new messages that are found. Each new\n"
   "\t\tmessage will be tagged as both \"inbox\" and \"unread\".\n"
@@ -122,6 +122,13 @@ 

[notmuch] lots of emacs mode enhancements

2009-11-23 Thread Carl Worth
On Mon, 23 Nov 2009 00:11:22 +0100, Carl Worth  wrote:
> On Fri, 20 Nov 2009 00:26:33 -0800, Alexander Botero-Lowry  at gmail.com> wrote:
> I really like the bold headers. And I can tell that the buttonization is
> going to be very nice. But I can't actually get it to work completely. I
> first clicked[*] on a signature to make it visible, which worked
> find. But then clicking on it again I got "buffer is read-only" and it
> wouldn't hide. At that point I couldn't get any of the other buttons to
> make things visible either.

This was simply a re-display bug which Alexander fixed. And he also
changed the buttons from button-2 to button-1.

I really like the final result, so it's pushed now.

Citations and signatures can now be expanded locally!

It is slightly harder to do this with the keyboard now. You have to
actually position point right on the button. This is just a temporary
thing, as I want to add a TAB binding to move point to the next button.

So keyboard-lovers, don't worry, notmuch (at least the emacs interface)
will always be very friendly for keyboard use (excepting temporary
lapses like this current one).

-Carl


[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags

2009-11-23 Thread Carl Worth
On Tue, 17 Nov 2009 13:32:45 -0800, Keith Packard  wrote:
> When closing a thread view, mark the thread as archived by removing
> the "inbox" tag, and for the 'x' variant, the "unread" tag as well,
> then kill the buffer and update the search window view as well.

I'm starting to come around to this patch, Keith. :-)

I think one thing we're going to really need is a better help message
for presenting the keybindings. The function names are all really
confusing, (the "notmuch-show" prefix doesn't help). So what I'd really
like is something that displays the keybinding and the first line of the
documentation of a function, rather than the function name itself.

> This makes 'x' much the same as 'a', but instead of taking you to the
> next message, it takes you back to the search window instead.

Except that the patch also reverses the current behavior of "a" and
"A". That should be a separate patch anyway, but I'm also not sure that
I like it. I like that the command that takes the extra effort of
pressing shift is the command that does *more*, (removing both "unread"
and "inbox"), rather than the command that does *less*.

-Carl


[notmuch] lots of emacs mode enhancements

2009-11-23 Thread Carl Worth
On Fri, 20 Nov 2009 00:26:33 -0800, Alexander Botero-Lowry  wrote:
> I've just been diving into the elisp, and have added a bunch of useful
> features.

This is fantastic stuff, Alex. Thanks so much for working on it. (And
I'm sorry it took me a while before I got around to reviewing
it. Hopefully I'll be more responsive when I'm done travelling in a
couple of days.

> 1) buttonized citation and signature expanders and made them locally
> collapsable instead of globally 
> 2) fixed an annoying warning about cons not being a face name
> 3) made header names bold to make it easier to distingush them from
> their value

I really like the bold headers. And I can tell that the buttonization is
going to be very nice. But I can't actually get it to work completely. I
first clicked[*] on a signature to make it visible, which worked
find. But then clicking on it again I got "buffer is read-only" and it
wouldn't hide. At that point I couldn't get any of the other buttons to
make things visible either.

So, being unwilling to have hidden content that I can't make visible, I
can't merge this work in its current state. If you can't replicate the
bug, let me know and I'll try to look closer at what's going on.

> (this could take some cleanup to remove
> the global key-map binding or make it work again)

Obviously, we should not have a keybinding that doesn't work. But I'd be
glad to just remove it---if we can do local expansion I don't see a big
reason to have global expansion. At least for things like citations and
signature. For message bodies, that's different, so I can imagine having
an "expand all" keybinding for them.

Meanwhile, the feature that I *will* want is something to make it easy
to use the keyboard alone to show/hide hidden parts. What I want is for
TAB to advance to the next button, so that then I can just press RET on
it to toggle it.

> My next target is to carry the buttonization through to threads and
> headers, and then I'm going to look into doing better mime-handling in
> general.

Great. I'll look forward to that.

> also, RFP includes a -p argument that gives a patch :)

Very nice. It's appreciated.

-Carl

[*] Any reason we can't make button 1 do this instead of button 2? That
should be more intuitive, and at worst it means that the text on the
button itself is hard to select, which shouldn't be an option.