Distributed Notmuch

2012-01-08 Thread Ethan Glasser-Camp

Hi guys,

It's kind of academic for me right now because I'm mostly just using one 
computer, but one reason I've hesitated to switch over entirely to 
notmuch is that it's hard to distribute across many machines. The last 
time I wrote the list about this, David Bremner pointed me to gitmuch in 
the notmuch-scripts package, which uses git to synchronize tags. He 
wrote, "No one claims this is a great solution, but it works now."


In brainstorming about the One True Mail Setup, my friend suggested to 
me that Maildir/IMAP are not really the best choices for mail storage. 
Among other flaws: to synchronize mail via IMAP you have to check the 
headers of each message, which means a lot of bandwidth; you can't 
compress Maildir, meaning lots of wasted space; mechanisms to 
synchronize arbitrary tags have to be bolted on top. My friend suggested 
that instead it might be better to dump mail into some kind of database, 
for example CouchDB, and synchronize it that way. Of course, doing 
full-text indexing and tagging using an arbitrary DB would be a ton of 
work, so instead it probably makes the most sense to keep a Xapian 
instance on each node and feed all the mail to that. Tagging operations 
still have to be replicated, probably by an oplog that's also kept in 
Couch, so it's still a lot of work, but keeping things in Couch 
automatically gets you a lot of the replication mechanisms, offline 
access, etc., that would have to be bolted on/hacked up using tools like 
nmbug/gitmuch/rsync. I also see in the wiki that someone proposes to use 
git as the mail store, presumably for similar reasons. Xapian itself has 
the idea of master/slave replication but that doesn't really get you 
full offline access.


So my question for the wizards on this list is what their idea of the 
One True Mail Setup would be in a perfect, or slightly better, world, 
and what needs to be done to get there. I know some people use one 
notmuch install that they access remotely. For myself, I'm on a pretty 
limited Internet connection, so low bandwidth/offline access are big for 
me, and despite Nicolas Sebrecht and Sebastian Spaeth's heroic work on 
OfflineIMAP, it still uses a lot of bandwidth to sync. And obviously the 
whole point of this exercise is tag synchronization..


Ethan

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


Re: [PATCH 1/2] clean up "compare thread ids" python test

2012-01-08 Thread Sebastian Spaeth
On Mon,  2 Jan 2012 14:51:26 +, Patrick Totzke 
 wrote:
> This makes the test script open the database in READ_ONLY mode
> and use the libraries own sorting methods instead of "sort".

+1 I don't want to fudge the tests (I don't know a thing about them), so
I can't judge the test outcome, but it is certainly good from the python side of
things. So I'll push this one.


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


Re: [PATCH 1/4] Add the option "--reply-to" to notmuch reply.

2012-01-08 Thread Jani Nikula
On Fri,  6 Jan 2012 13:34:14 +, Mark Walters  
wrote:
> Possible values for this option are "sender" which replies just to
> sender and "all" (the default).
> 
> More precisely reply to sender follows these rules:
> reply only to sender unless it was the user
> reply only to all people on the "to" line unless they were all the user
> reply to all people on the "cc" line
> 
> Implementation details
> 
> We continue parsing addresses beyond the ones we reply to because
> we want to make sure the from address is correct. (At the very least it
> is the same as it would be if we replied to all.)
> 
> We overload the message variable in add_recipients_for_address_list so
> if it is NULL we parse the address (looking for the users address)
> but do not add to the message recipients list
> 
> We add the variable reply_to_all to the function chain to keep track
> of whether we should reply to everyone.
> ---
>  notmuch-reply.c |   48 +---
>  1 files changed, 37 insertions(+), 11 deletions(-)
> 
> diff --git a/notmuch-reply.c b/notmuch-reply.c
> index f8d5f64..9a77fe6 100644
> --- a/notmuch-reply.c
> +++ b/notmuch-reply.c
> @@ -212,7 +212,8 @@ add_recipients_for_address_list (GMimeMessage *message,
>   if (ret == NULL)
>   ret = addr;
>   } else {
> - g_mime_message_add_recipient (message, type, name, addr);
> +  if (message)
> +   g_mime_message_add_recipient (message, type, name, addr);
>   }
>   }
>  }
> @@ -292,7 +293,8 @@ reply_to_header_is_redundant (notmuch_message_t *message)
>  static const char *
>  add_recipients_from_message (GMimeMessage *reply,
>notmuch_config_t *config,
> -  notmuch_message_t *message)
> +  notmuch_message_t *message,
> +  int reply_to_all)
>  {
>  struct {
>   const char *header;
> @@ -332,9 +334,20 @@ add_recipients_from_message (GMimeMessage *reply,
>   recipients = notmuch_message_get_header (message,
>reply_to_map[i].fallback);
>  
> - addr = add_recipients_for_string (reply, config,
> -   reply_to_map[i].recipient_type,
> -   recipients);
> +
> + /* We add the addresses if we are replying to all or we have not yet 
> found
> +  * a non-user address. We have to keep parsing to make sure we do find 
> the
> +  * correct from address for the user, but we pass a NULL message
> +  */
> + if ((reply_to_all) || (g_mime_message_get_all_recipients (reply) == 
> NULL))

Looking into this, it occurred to me g_mime_message_get_all_recipients()
allocates a new InternetAddressList when the return value is
non-NULL. Thus this leaks memory. OTOH allocating and deallocating for
this purpose seems suboptimal. I'll think this over.

BR,
Jani.



> + addr = add_recipients_for_string (reply, config,
> +   reply_to_map[i].recipient_type,
> +   recipients);
> + else
> +  addr = add_recipients_for_string (NULL, config,
> +reply_to_map[i].recipient_type,
> +recipients);
> +
>   if (from_addr == NULL)
>   from_addr = addr;
>  }
> @@ -480,7 +493,8 @@ static int
>  notmuch_reply_format_default(void *ctx,
>notmuch_config_t *config,
>notmuch_query_t *query,
> -  notmuch_show_params_t *params)
> +  notmuch_show_params_t *params,
> +  int reply_to_all)
>  {
>  GMimeMessage *reply;
>  notmuch_messages_t *messages;
> @@ -509,7 +523,7 @@ notmuch_reply_format_default(void *ctx,
>   g_mime_message_set_subject (reply, subject);
>   }
>  
> - from_addr = add_recipients_from_message (reply, config, message);
> + from_addr = add_recipients_from_message (reply, config, message, 
> reply_to_all);
>  
>   if (from_addr == NULL)
>   from_addr = guess_from_received_header (config, message);
> @@ -558,7 +572,8 @@ static int
>  notmuch_reply_format_headers_only(void *ctx,
> notmuch_config_t *config,
> notmuch_query_t *query,
> -   unused (notmuch_show_params_t *params))
> +   unused (notmuch_show_params_t *params),
> +   int reply_to_all)
>  {
>  GMimeMessage *reply;
>  notmuch_messages_t *messages;
> @@ -598,7 +613,7 @@ notmuch_reply_format_headers_only(void *ctx,
>   g_mime_object_set_header (GMIME_OBJECT (reply),
>

Re: [PATCH 2/2] python test "compare message ids"

2012-01-08 Thread Sebastian Spaeth
On Mon,  2 Jan 2012 14:51:27 +, Patrick Totzke 
 wrote:
> Introduces a second (trivial) test for the python
> bindings that searches for message ids and compares
> the output with that of `notmuch search`.

Test passes, so it went in.


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


notmuch git's disk is full! ERROR pushing.

2012-01-08 Thread Sebastian Spaeth
Actually trying to push the above 2 patches, I get 

Writing objects: 100% (8/8), 1.25 KiB, done.
Total 8 (delta 5), reused 0 (delta 0)
error: unable to create temporary sha1 filename : No space left on device

fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
To ssh://spa...@notmuchmail.org/git/notmuch
 ! [remote rejected] master -> master (n/a (unpacker error))
error: failed to push some refs to 'ssh://spa...@notmuchmail.org/git/notmuch'

Sebastian


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


Re: Info about notmuch database

2012-01-08 Thread Sebastian Spaeth
On Thu, 05 Jan 2012 16:04:22 +0100, Thomas Jost  wrote:
> There's a description of the DB "schema" in lib/database.cc in the
> notmuch source code. But you may also consider just using libnotmuch
> instead, if that's enough for what you want to do.
> 
> Also: why Xapian? I'm already using something similar I wrote with
> Python, storing everything in a dictionary, using Pickle to save that to
> disk: 162 lines of code and 45 kb of data are enough to store my
> addressbook and have completion in Emacs...

Ohh, that sounds nice. Is that public somewhere?

Sebastian


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


Re: [PATCH 5/7] py3k: the basestring and unicode types are removed in python 3

2012-01-08 Thread Justus Winter
Hi Tomi, Hi Sebastian :)

Quoting Tomi Ollila (2012-01-04 19:07:11)
>On Mon, 02 Jan 2012 16:15:58 +0100, Sebastian Spaeth  
>wrote:
>> Happy new year. Pushed patches 1-4 of this series so far. Looking fine,

nice, thanks.

>> but ugh, the below seems like a rather ugly hack in a function that is
>> probably called quite often.
>>
>> Isn't there a more pretty variant avoiding these sys.version_info checks
>> all over the place?

Well, I rebased and updated this patch. There are now two different
implementations of _str like there are two Python3StringMixIn
classes. I'll send this patch as reply to this message.

>Does the Python3StringMixIn stuff in later patches already handle this
>patch -- and making this obsolete ?

No, that only handles the __str__ and __unicode__ stuff.

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


[PATCH] py3k: the basestring and unicode types are removed in python 3

2012-01-08 Thread Justus Winter
---
 bindings/python/notmuch/globals.py |   34 ++
 1 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/bindings/python/notmuch/globals.py 
b/bindings/python/notmuch/globals.py
index 32ed9ae..4138460 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -31,12 +31,34 @@ if sys.version_info[0] == 2:
 class Python3StringMixIn(object):
 def __str__(self):
 return unicode(self).encode('utf-8')
+
+
+def _str(value):
+"""Ensure a nicely utf-8 encoded string to pass to libnotmuch
+
+C++ code expects strings to be well formatted and
+unicode strings to have no null bytes."""
+if not isinstance(value, basestring):
+raise TypeError("Expected str or unicode, got %s" % type(value))
+if isinstance(value, unicode):
+return value.encode('UTF-8')
+return value
 else:
 class Python3StringMixIn(object):
 def __str__(self):
 return self.__unicode__()
 
 
+def _str(value):
+"""Ensure a nicely utf-8 encoded string to pass to libnotmuch
+
+C++ code expects strings to be well formatted and
+unicode strings to have no null bytes."""
+if not isinstance(value, str):
+raise TypeError("Expected str, got %s" % type(value))
+return value.encode('UTF-8')
+
+
 class Enum(object):
 """Provides ENUMS as "code=Enum(['a','b','c'])" where code.a=0 etc..."""
 def __init__(self, names):
@@ -202,18 +224,6 @@ class NotInitializedError(NotmuchError):
 status = STATUS.NOT_INITIALIZED
 
 
-def _str(value):
-"""Ensure a nicely utf-8 encoded string to pass to libnotmuch
-
-C++ code expects strings to be well formatted and
-unicode strings to have no null bytes."""
-if not isinstance(value, basestring):
-raise TypeError("Expected str or unicode, got %s" % str(type(value)))
-if isinstance(value, unicode):
-return value.encode('UTF-8')
-return value
-
-
 class NotmuchDatabaseS(Structure):
 pass
 NotmuchDatabaseP = POINTER(NotmuchDatabaseS)
-- 
1.7.7.3

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


Re: Info about notmuch database

2012-01-08 Thread Thomas Jost
On Sun, 08 Jan 2012 13:59:30 +0100, Sebastian Spaeth  
wrote:
> On Thu, 05 Jan 2012 16:04:22 +0100, Thomas Jost  wrote:
> > There's a description of the DB "schema" in lib/database.cc in the
> > notmuch source code. But you may also consider just using libnotmuch
> > instead, if that's enough for what you want to do.
> > 
> > Also: why Xapian? I'm already using something similar I wrote with
> > Python, storing everything in a dictionary, using Pickle to save that to
> > disk: 162 lines of code and 45 kb of data are enough to store my
> > addressbook and have completion in Emacs...
> 
> Ohh, that sounds nice. Is that public somewhere?
> 
> Sebastian

https://github.com/Schnouki/dotfiles/blob/master/notmuch/addrbook.py

Maybe I should add more comments in it :)

Regards,

-- 
Thomas/Schnouki


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


Re: [PATCH 1/4] Add the option "--reply-to" to notmuch reply.

2012-01-08 Thread Mark Walters

On Sun, 08 Jan 2012 14:47:33 +0200, Jani Nikula  wrote:
> > +   /* We add the addresses if we are replying to all or we have not yet 
> > found
> > +* a non-user address. We have to keep parsing to make sure we do find 
> > the
> > +* correct from address for the user, but we pass a NULL message
> > +*/
> > +   if ((reply_to_all) || (g_mime_message_get_all_recipients (reply) == 
> > NULL))
> 
> Looking into this, it occurred to me g_mime_message_get_all_recipients()
> allocates a new InternetAddressList when the return value is
> non-NULL. Thus this leaks memory. OTOH allocating and deallocating for
> this purpose seems suboptimal. I'll think this over.

If we are happy with reply-to-sender stopping at the to: line
(so if you reply-to-sender to an email which you sent and has no-one
(apart from possibly you) on the to: line it would not give any
recipients) then we only have two cases and we could do something like

add_recipients_for_string for reply-to:/from:

if return value is non-null then we were the sender so then

add_recipients_for_string for to:

and then stop regardless (well we want to carry on parsing headers to
find the correct from: address to use but not adding any more
recipients).

It feels a bit hackish (it relies on the fact that if we found our
address in the Reply-to:/From: line we didn't find anyone else's
address). 

I think replying to an email which we sent and which does not have any
other person on the to: line is sufficiently rare that it doesn't really
matter what we do in this case.

Best wishes

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


Re: [PATCH 1/4] Add the option "--reply-to" to notmuch reply.

2012-01-08 Thread Jani Nikula
On Sun, 08 Jan 2012 15:08:20 +, Mark Walters  
wrote:
> I think replying to an email which we sent and which does not have any
> other person on the to: line is sufficiently rare that it doesn't really
> matter what we do in this case.

I ended up fixing all of this properly. I'm hoping to send the patches
later today so you can have a look - the code will do a better job of
explaining itself than I'd do now. :)

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


Re: Python bindings for adoption

2012-01-08 Thread Justus Winter
Hi Sebastian, hi everyone :)

Quoting Sebastian Spaeth (2012-01-02 17:14:58)
>Hi all, a happy new year!
>
>After a few weeks of notmuch abstinence I am being overwhelmed with 750
>new notmuch mails, and I really don't have the time or will (nor does my
>family approve) to spend enormous amounts of time on notmuch. I am
>already neglecting offlineimap, which also needs some attention.
>
>As I have repeatedly stated that I want to hand over the maintainership
>of the notmuch python bindings, and I would like to do it asap. I feel
>that people like Patrick Totzke, or Justus Winter who generally have
>been working on this far more intensely than I recently did are both
>very well positioned to take on that role :-). Most importantly, they
>actually work with the bindings while I don't use them myself anymore.
>
>I will only merge bug fixes as of now, and not invest time to refactor
>the code or add lots of bells and whistles. Let me know if anyone would
>volunteer to take them on.

I've decided to step up as a new maintainer for the libnotmuch python
bindings. I assume that I'll have to mail an ssh public key to someone
for repository access, right?

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


Re: nmbug changes

2012-01-08 Thread Justus Winter
Hey David,

Quoting David Bremner (2011-12-23 22:56:31)
>For those of you following/using the nmbug experiment, I made some
>slightly disruptive changes, in order to support auto-updating the web
>view on push.

I'm having trouble with nmbug, I did follow the instructions in this
mail and in the wiki, but nmbug never adds tags to my notmuch database
(it is supposed to do that, right?).

Consequently, nmbug status displays a long list of tags that aren't in
my notmuch database. Executing nmbug merge does not help, and stracing
nmbug revealed that it does only invoke notmuch with the search and
dump actions.

Any pointers?

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


[PATCH 4/4 v2] emacs: use pop-at-end functionality in archive/delete-message functions

2012-01-08 Thread Jameson Graef Rollins
This provides a smoother message processing flow by reducing the
number of key presses needed for these common operations.
---
Sorry, there were some errant extra parens at the end of these
function definitions.

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

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 4c2b507..a706637 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1454,7 +1454,7 @@ thread.
 "
 (interactive)
 (notmuch-show-remove-tag "inbox")
-(notmuch-show-next-open-message)))
+(notmuch-show-next-open-message t))
 
 (defun notmuch-show-archive-thread ()
   "Archive each message in thread, then show next thread from search.
@@ -1485,7 +1485,7 @@ thread.
 "
 (interactive)
 (notmuch-show-add-tag "deleted")
-(notmuch-show-next-open-message)))
+(notmuch-show-next-open-message t))
 
 (defun notmuch-show-delete-thread ()
   "Delete each message in thread, then show next thread from search.
-- 
1.7.7.3

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


[PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message

2012-01-08 Thread Jameson Graef Rollins
This adds two new function, notmuch-show-{archive,delete}-message,
that archive/delete the current message, and then move to the next
open one.
---
Sorry, there were some errant extra parens at the end of these
function definitions.

 emacs/notmuch-show.el |   24 
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index e1d15f4..b2e7829 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1436,6 +1436,18 @@ argument, hide all of the messages."
(if show-next
(notmuch-search-show-thread)))
 
+(defun notmuch-show-archive-message ()
+  "Archive the current message and advance.
+
+After the last message is reached, either the buffer will be
+closed and the cursor will move to the search result if
+available, or the cursor will move to the end of the current
+thread.
+"
+(interactive)
+(notmuch-show-remove-tag "inbox")
+(notmuch-show-next-open-message))
+
 (defun notmuch-show-archive-thread ()
   "Archive each message in thread, then show next thread from search.
 
@@ -1455,6 +1467,18 @@ buffer."
   (interactive)
   (notmuch-show-tag-thread-internal "-" "inbox" nil))
 
+(defun notmuch-show-delete-message ()
+  "Delete the current message and advance.
+
+After the last message is reached, either the buffer will be
+closed and the cursor will move to the search result if
+available, or the cursor will move to the end of the current
+thread.
+"
+(interactive)
+(notmuch-show-add-tag "deleted")
+(notmuch-show-next-open-message))
+
 (defun notmuch-show-delete-thread ()
   "Delete each message in thread, then show next thread from search.
 
-- 
1.7.7.3

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


[PATCH 4/4 v3] emacs: use pop-at-end functionality in archive/delete-message functions

2012-01-08 Thread Jameson Graef Rollins
This provides a smoother message processing flow by reducing the
number of key presses needed for these common operations.
---
Sorry sorry.  I originally missed the problem in patch 1/4, so I had
to modify this patch again to apply against the new version of the
previous.  So sorry for the noise, and thanks to amdragon for pointing
all of this out.

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

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b9ec584..a706637 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1454,7 +1454,7 @@ thread.
 "
 (interactive)
 (notmuch-show-remove-tag "inbox")
-(notmuch-show-next-open-message))
+(notmuch-show-next-open-message t))
 
 (defun notmuch-show-archive-thread ()
   "Archive each message in thread, then show next thread from search.
@@ -1485,7 +1485,7 @@ thread.
 "
 (interactive)
 (notmuch-show-add-tag "deleted")
-(notmuch-show-next-open-message))
+(notmuch-show-next-open-message t))
 
 (defun notmuch-show-delete-thread ()
   "Delete each message in thread, then show next thread from search.
-- 
1.7.7.3

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


[PATCH] man: add missing SEE ALSO header to notmuch reply man page

2012-01-08 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 man/man1/notmuch-reply.1 |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 099d808..db464d8 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -58,6 +58,9 @@ thread, replying to the entire thread allows for the reply to 
comment
 on issue found in multiple patches.
 .RE
 .RE
+
+.SH SEE ALSO
+
 \fBnotmuch\fR(1), \fBnotmuch-config\fR(1), \fBnotmuch-count\fR(1),
 \fBnotmuch-dump\fR(5), \fBnotmuch-hooks\fR(5), \fBnotmuch-new\fR(1),
 \fBnotmuch-part\fR(1), \fBnotmuch-restore\fR(1),
-- 
1.7.5.4

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


[PATCH v2 0/6] reply to sender

2012-01-08 Thread Jani Nikula
Hi all, here's v2 of the reply-to-sender series.

Patches 1 & 2 are exactly the same as before.

Changes since first version:

- Patch 3: Settle on --reply-to=(all|sender) option for "notmuch
  reply". This was originally Carl Worth's suggestion, predates this
  patch set, and, as you'd expect, is in line with the rest of the
  CLI. Acked by David on IRC.

- Patch 3: Handle replying to user's own messages gracefully. Credits
  to Mark Walters for his earlier work on this.

- Patch 3: Update man page.

- Patch 4: Change emacs implementation to keep old function names for
  old reply-to-all functionality, and add new reply-to-sender versions
  for new functionality, instead of vice versa. Suggested by Mark
  Walters.

- Add patch 5 to change emacs keybindings, 'r' for reply-to-sender,
  'R' for reply-to-all. I think everyone was in favour of this.

- Add patch 6, written by Mark Winters, to test the cli.

Comments are, as always, welcome.


BR,
Jani.

Jani Nikula (5):
  cli: fix use of uninitialized variable in "notmuch reply"
  cli: convert "notmuch reply" to use the new argument parser
  cli: add support for replying just to the sender in "notmuch reply"
  emacs: add support for replying just to the sender
  emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

Mark Walters (1):
  test: add tests for "notmuch reply" --reply-to=sender

 emacs/notmuch-mua.el |9 ++-
 emacs/notmuch-show.el|   12 ++-
 emacs/notmuch.el |   11 ++-
 man/man1/notmuch-reply.1 |   28 +-
 notmuch-reply.c  |  155 ++
 test/notmuch-test|1 +
 test/reply-to-sender |  209 ++
 7 files changed, 356 insertions(+), 69 deletions(-)
 create mode 100755 test/reply-to-sender

-- 
1.7.5.4

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


[PATCH v2 1/6] cli: fix use of uninitialized variable in "notmuch reply"

2012-01-08 Thread Jani Nikula
notmuch_show_params_t params is only initialized partially in
notmuch_reply_command(). The only field that is used uninitialized is
params.decrypt. It is usually non-zero, making "notmuch reply" on encrypted
messages work by coincidence.

Initialize params properly, and set params.decrypt as needed.

Signed-off-by: Jani Nikula 
---
 notmuch-reply.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index f8d5f64..1f33a86 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -621,11 +621,9 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 char *opt, *query_string;
 int i, ret = 0;
 int (*reply_format_func)(void *ctx, notmuch_config_t *config, 
notmuch_query_t *query, notmuch_show_params_t *params);
-notmuch_show_params_t params;
+notmuch_show_params_t params = { .part = -1 };
 
 reply_format_func = notmuch_reply_format_default;
-params.part = -1;
-params.cryptoctx = NULL;
 
 argc--; argv++; /* skip subcommand argument */
 
@@ -647,10 +645,12 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
} else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
if (params.cryptoctx == NULL) {
GMimeSession* session = g_object_new(g_mime_session_get_type(), 
NULL);
-   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
"gpg")))
+   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
"gpg"))) {
fprintf (stderr, "Failed to construct gpg context.\n");
-   else
+   } else {
+   params.decrypt = TRUE;

g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
+   }
g_object_unref (session);
session = NULL;
}
-- 
1.7.5.4

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


[PATCH v2 2/6] cli: convert "notmuch reply" to use the new argument parser

2012-01-08 Thread Jani Nikula
Use the new notmuch argument parser to handle arguments in "notmuch
reply". There should be no functional changes.

Signed-off-by: Jani Nikula 
---
 notmuch-reply.c |   75 +++
 1 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 1f33a86..000f6da 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -612,62 +612,61 @@ notmuch_reply_format_headers_only(void *ctx,
 return 0;
 }
 
+enum {
+FORMAT_DEFAULT,
+FORMAT_HEADERS_ONLY,
+};
+
 int
 notmuch_reply_command (void *ctx, int argc, char *argv[])
 {
 notmuch_config_t *config;
 notmuch_database_t *notmuch;
 notmuch_query_t *query;
-char *opt, *query_string;
-int i, ret = 0;
+char *query_string;
+int opt_index, ret = 0;
 int (*reply_format_func)(void *ctx, notmuch_config_t *config, 
notmuch_query_t *query, notmuch_show_params_t *params);
 notmuch_show_params_t params = { .part = -1 };
+int format = FORMAT_DEFAULT;
+notmuch_bool_t decrypt = FALSE;
+
+notmuch_opt_desc_t options[] = {
+   { NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
+ (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
+ { "headers-only", FORMAT_HEADERS_ONLY },
+ { 0, 0 } } },
+   { NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
+   { 0, 0, 0, 0, 0 }
+};
 
-reply_format_func = notmuch_reply_format_default;
-
-argc--; argv++; /* skip subcommand argument */
+opt_index = parse_arguments (argc, argv, options, 1);
+if (opt_index < 0) {
+   /* diagnostics already printed */
+   return 1;
+}
 
-for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-   if (strcmp (argv[i], "--") == 0) {
-   i++;
-   break;
-   }
-if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-   opt = argv[i] + sizeof ("--format=") - 1;
-   if (strcmp (opt, "default") == 0) {
-   reply_format_func = notmuch_reply_format_default;
-   } else if (strcmp (opt, "headers-only") == 0) {
-   reply_format_func = notmuch_reply_format_headers_only;
-   } else {
-   fprintf (stderr, "Invalid value for --format: %s\n", opt);
-   return 1;
-   }
-   } else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
-   if (params.cryptoctx == NULL) {
-   GMimeSession* session = g_object_new(g_mime_session_get_type(), 
NULL);
-   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
"gpg"))) {
-   fprintf (stderr, "Failed to construct gpg context.\n");
-   } else {
-   params.decrypt = TRUE;
-   
g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
-   }
-   g_object_unref (session);
-   session = NULL;
-   }
+if (format == FORMAT_HEADERS_ONLY)
+   reply_format_func = notmuch_reply_format_headers_only;
+else
+   reply_format_func = notmuch_reply_format_default;
+
+if (decrypt) {
+   GMimeSession* session = g_object_new (g_mime_session_get_type(), NULL);
+   params.cryptoctx = g_mime_gpg_context_new (session, "gpg");
+   if (params.cryptoctx) {
+   g_mime_gpg_context_set_always_trust ((GMimeGpgContext*) 
params.cryptoctx, FALSE);
+   params.decrypt = TRUE;
} else {
-   fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
-   return 1;
+   fprintf (stderr, "Failed to construct gpg context.\n");
}
+   g_object_unref (session);
 }
 
-argc -= i;
-argv += i;
-
 config = notmuch_config_open (ctx, NULL, NULL);
 if (config == NULL)
return 1;
 
-query_string = query_string_from_args (ctx, argc, argv);
+query_string = query_string_from_args (ctx, argc-opt_index, 
argv+opt_index);
 if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return 1;
-- 
1.7.5.4

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


[PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"

2012-01-08 Thread Jani Nikula
Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
to reply to all (sender and all recipients), or just sender. Reply to all
remains the default.

Credits to Mark Walters  for his similar earlier
work where I picked up the basic idea of handling reply-to-sender in
add_recipients_from_message(). All bugs are mine, though.

Signed-off-by: Jani Nikula 

---

Settled on --reply-to=(all|sender) per Carl's earlier suggestion
(id:87pqn5cg4g@yoom.home.cworth.org) and David's approval on IRC.
---
 man/man1/notmuch-reply.1 |   28 +---
 notmuch-reply.c  |   78 --
 2 files changed, 84 insertions(+), 22 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 099d808..21afa35 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
 To make replying to email easier,
 .B notmuch reply
 takes an existing set of messages and constructs a suitable mail
-template. The Reply-to header (if any, otherwise From:) is used for
-the To: address. Vales from the To: and Cc: headers are copied, but
-not including any of the current user's email addresses (as configured
-in primary_mail or other_email in the .notmuch\-config file) in the
-recipient list
+template. The Reply-to: header (if any, otherwise From:) is used for
+the To: address. Unless
+.BR \-\-reply-to=sender
+is specified, values from the To: and Cc: headers are copied, but not
+including any of the current user's email addresses (as configured in
+primary_mail or other_email in the .notmuch\-config file) in the
+recipient list.
 
 It also builds a suitable new subject, including Re: at the front (if
 not already present), and adding the message IDs of the messages being
@@ -45,6 +47,22 @@ Includes subject and quoted message body.
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
 .RE
+.RS
+.TP 4
+.BR \-\-reply\-to= ( all | sender )
+.RS
+.TP 4
+.BR all " (default)"
+Replies to all addresses.
+.TP 4
+.BR sender
+Replies only to the sender. If Reply-to: header (if any, otherwise
+From:) is any of the current user's configured email addresses
+(replying to user's own message), try To:, Cc:, and Bcc: headers in
+this order, and use the addresses in the first that contains something
+other than only the user's addresses for the To: address.
+.RE
+.RE
 
 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for .
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 000f6da..71946b3 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -170,7 +170,7 @@ address_is_users (const char *address, notmuch_config_t 
*config)
 
 /* For each address in 'list' that is not configured as one of the
  * user's addresses in 'config', add that address to 'message' as an
- * address of 'type'.
+ * address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -179,7 +179,8 @@ static const char *
 add_recipients_for_address_list (GMimeMessage *message,
 notmuch_config_t *config,
 GMimeRecipientType type,
-InternetAddressList *list)
+InternetAddressList *list,
+notmuch_bool_t add)
 {
 InternetAddress *address;
 int i;
@@ -197,7 +198,7 @@ add_recipients_for_address_list (GMimeMessage *message,
continue;
 
add_recipients_for_address_list (message, config,
-type, group_list);
+type, group_list, add);
} else {
InternetAddressMailbox *mailbox;
const char *name;
@@ -211,7 +212,7 @@ add_recipients_for_address_list (GMimeMessage *message,
if (address_is_users (addr, config)) {
if (ret == NULL)
ret = addr;
-   } else {
+   } else if (add) {
g_mime_message_add_recipient (message, type, name, addr);
}
}
@@ -222,7 +223,7 @@ add_recipients_for_address_list (GMimeMessage *message,
 
 /* For each address in 'recipients' that is not configured as one of
  * the user's addresses in 'config', add that address to 'message' as
- * an address of 'type'.
+ * an address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -231,7 +232,8 @@ static const char *
 add_recipients_for_string (GMimeMessage *message,
   notmuch_config_t *config,
   GMimeRecipientType type,
-  const char *recipients)
+  const char *recipients,
+  notmuch_bool_t add)
 {
 InternetAddressLi

[PATCH v2 4/6] emacs: add support for replying just to the sender

2012-01-08 Thread Jani Nikula
Provide reply to sender counterparts to the search and show reply
functions. Add key binding 'R' to reply to sender, while keeping 'r' as
reply to all, both in search and show views.

Signed-off-by: Jani Nikula 
---
 emacs/notmuch-mua.el  |9 ++---
 emacs/notmuch-show.el |   10 --
 emacs/notmuch.el  |9 -
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7114e48..5b15255 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,15 @@ list."
(push header message-hidden-headers)))
notmuch-mua-hidden-headers))
 
-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string &optional sender reply-all)
   (let (headers
body
(args '("reply")))
 (if notmuch-show-process-crypto
(setq args (append args '("--decrypt"
+(if reply-all
+   (setq args (append args '("--reply-to=all")))
+  (setq args (append args '("--reply-to=sender"
 (setq args (append args (list query-string)))
 ;; This make assumptions about the output of `notmuch reply', but
 ;; really only that the headers come first followed by a blank
@@ -217,13 +220,13 @@ the From: address first."
(notmuch-mua-forward-message))
 (notmuch-mua-forward-message)))
 
-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender 
reply-all)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 (when prompt-for-sender
   (notmuch-mua-prompt-for-sender
-(notmuch-mua-reply query-string sender)))
+(notmuch-mua-reply query-string sender reply-all)))
 
 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..96eea19 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -933,6 +933,7 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
(define-key map "m" 'notmuch-mua-new-mail)
(define-key map "f" 'notmuch-show-forward-message)
(define-key map "r" 'notmuch-show-reply)
+   (define-key map "R" 'notmuch-show-reply-sender)
(define-key map "|" 'notmuch-show-pipe-message)
(define-key map "w" 'notmuch-show-save-attachments)
(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1237,9 +1238,14 @@ any effects from previous calls to
   (notmuch-show-previous-message)
 
 (defun notmuch-show-reply (&optional prompt-for-sender)
-  "Reply to the current message."
+  "Reply to the sender and all recipients of the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t))
+
+(defun notmuch-show-reply-sender (&optional prompt-for-sender)
+  "Reply to the sender of the current message."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil))
 
 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index fde2377..5974d6b 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -207,6 +207,7 @@ For a mouse binding, return nil."
 (define-key map "p" 'notmuch-search-previous-thread)
 (define-key map "n" 'notmuch-search-next-thread)
 (define-key map "r" 'notmuch-search-reply-to-thread)
+(define-key map "R" 'notmuch-search-reply-to-thread-sender)
 (define-key map "m" 'notmuch-mua-new-mail)
 (define-key map "s" 'notmuch-search)
 (define-key map "o" 'notmuch-search-toggle-order)
@@ -441,10 +442,16 @@ Complete list of currently available key bindings:
   (error "End of search results"
 
 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
+  "Begin composing a reply-all to the entire current thread in a new buffer."
+  (interactive "P")
+  (let ((message-id (notmuch-search-find-thread-id)))
+(notmuch-mua-new-reply message-id prompt-for-sender t)))
+
+(defun notmuch-search-reply-to-thread-sender (&optional prompt-for-sender)
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-(notmuch-mua-new-reply message-id prompt-for-sender)))
+(notmuch-mua-new-reply message-id prompt-for-sender nil)))
 
 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.5.4

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


[PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jani Nikula
Change the default reply key bindings, making 'r' reply-to-sender and 'R'
reply-to-all.

Signed-off-by: Jani Nikula 

---

It seemed to me that most people wanted this, and nobody spoke for keeping
the old binding now that we have reply-to-sender. This as a separate patch
so it's easy to drop if needed.
---
 emacs/notmuch-show.el |4 ++--
 emacs/notmuch.el  |4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 96eea19..8f8ea93 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -932,8 +932,8 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
(define-key map "s" 'notmuch-search)
(define-key map "m" 'notmuch-mua-new-mail)
(define-key map "f" 'notmuch-show-forward-message)
-   (define-key map "r" 'notmuch-show-reply)
-   (define-key map "R" 'notmuch-show-reply-sender)
+   (define-key map "r" 'notmuch-show-reply-sender)
+   (define-key map "R" 'notmuch-show-reply)
(define-key map "|" 'notmuch-show-pipe-message)
(define-key map "w" 'notmuch-show-save-attachments)
(define-key map "V" 'notmuch-show-view-raw-message)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 5974d6b..e158138 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -206,8 +206,8 @@ For a mouse binding, return nil."
 (define-key map ">" 'notmuch-search-last-thread)
 (define-key map "p" 'notmuch-search-previous-thread)
 (define-key map "n" 'notmuch-search-next-thread)
-(define-key map "r" 'notmuch-search-reply-to-thread)
-(define-key map "R" 'notmuch-search-reply-to-thread-sender)
+(define-key map "r" 'notmuch-search-reply-to-thread-sender)
+(define-key map "R" 'notmuch-search-reply-to-thread)
 (define-key map "m" 'notmuch-mua-new-mail)
 (define-key map "s" 'notmuch-search)
 (define-key map "o" 'notmuch-search-toggle-order)
-- 
1.7.5.4

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


[PATCH v2 6/6] test: add tests for "notmuch reply" --reply-to=sender

2012-01-08 Thread Jani Nikula
From: Mark Walters 

---

This is Mark's work; just a one line change by Jani to take into account a
minor change in replying to one's own message.
---
 test/notmuch-test|1 +
 test/reply-to-sender |  209 ++
 2 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100755 test/reply-to-sender

diff --git a/test/notmuch-test b/test/notmuch-test
index e40ef86..6a99ae3 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -33,6 +33,7 @@ TESTS="
   thread-naming
   raw
   reply
+  reply-to-sender
   dump-restore
   uuencode
   thread-order
diff --git a/test/reply-to-sender b/test/reply-to-sender
new file mode 100755
index 000..caceeb2
--- /dev/null
+++ b/test/reply-to-sender
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+test_description="\"notmuch reply --reply-to=sender\" in several variations"
+. ./test-lib.sh
+
+test_begin_subtest "Basic reply-to-sender"
+add_message '[from]="Sender "' \
+ [to]=test_su...@notmuchmail.org \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="basic reply-to-sender test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: notmuch-reply-test
+To: Sender 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Sender  wrote:
+> basic reply-to-sender test"
+
+test_begin_subtest "From Us, Basic reply to message"
+add_message '[from]="Notmuch Test Suite "' \
+'[to]="Recipient "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="basic reply-to-from-us test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: notmuch-reply-test
+To: Recipient 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Notmuch Test Suite 
 wrote:
+> basic reply-to-from-us test"
+
+test_begin_subtest "Multiple recipients"
+add_message '[from]="Sender "' \
+'[to]="test_su...@notmuchmail.org, Someone Else 
"' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="Multiple recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: notmuch-reply-test
+To: Sender 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Sender  wrote:
+> Multiple recipients"
+
+test_begin_subtest "From Us, Multiple TO recipients"
+add_message '[from]="Notmuch Test Suite "' \
+'[to]="Recipient , Someone Else 
"' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="From Us, Multiple TO recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: notmuch-reply-test
+To: Recipient , Someone Else 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Notmuch Test Suite 
 wrote:
+> From Us, Multiple TO recipients"
+
+test_begin_subtest "Reply with CC"
+add_message '[from]="Sender "' \
+ [to]=test_su...@notmuchmail.org \
+'[cc]="Other Parties "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: notmuch-reply-test
+To: Sender 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Sender  wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply with CC"
+add_message '[from]="Notmuch Test Suite "' \
+'[to]="Recipient "' \
+'[cc]="Other Parties "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: notmuch-reply-test
+To: Recipient 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Notmuch Test Suite 
 wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply no TO but with CC"
+add_message '[from]="Notmuch Test Suite "' \
+'[cc]="Other Parties "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 

+Subject: Re: notmuch-reply-te

Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jeremy Nickurak
On Sun, Jan 8, 2012 at 14:48, Jani Nikula  wrote:
> It seemed to me that most people wanted this, and nobody spoke for keeping
> the old binding now that we have reply-to-sender. This as a separate patch
> so it's easy to drop if needed.

FWIW, I generally prefer reply-all as the default. In my experience,
when a message is sent to a bunch of people, it's usually treated as a
"forum" discussion where everybody wants to be in on everything. Also,
once you've started composing, it's much easier to delete people you
don't want included than to add people who are no longer referenced in
the new buffer at all.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: nmbug changes

2012-01-08 Thread David Bremner
On Sun, 08 Jan 2012 16:24:06 -, Justus Winter 
<4win...@informatik.uni-hamburg.de> wrote:

> I'm having trouble with nmbug, I did follow the instructions in this
> mail and in the wiki, but nmbug never adds tags to my notmuch database
> (it is supposed to do that, right?).

In case you just want to load the tags in the git repo into your notmuch
database, try running "nmbug checkout".

It might be the instructions on "getting started" could be updated here?
Perhaps someone who has gotten started more recently can chime in here.

David

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


Re: Python bindings for adoption

2012-01-08 Thread David Bremner
On Sun, 08 Jan 2012 16:16:06 -, Justus Winter 
<4win...@informatik.uni-hamburg.de> wrote:
> 
> I've decided to step up as a new maintainer for the libnotmuch python
> bindings. I assume that I'll have to mail an ssh public key to someone
> for repository access, right?
> 

That's right. Carl (in copy) handles repository access.

d



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


Re: [PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"

2012-01-08 Thread Mark Walters

I like this version (of the whole series) but have two queries. (Note I
haven't actually tried it out yet: I have just been reading the code.)

> + /* Force recipient type in reply-to-sender mode just in case replying to
> +  * user's own message finds recipients in Cc/Bcc fields only.
> +  */
> + if (reply_all)
> + recipient_type = reply_to_map[i].recipient_type;
> + else
> + recipient_type = GMIME_RECIPIENT_TYPE_TO;
> +
> + addr = add_recipients_for_string (reply, config, recipient_type,
> +   recipients, add_recipients);
> +

Why force the recipient type?  I do not think notmuch should ever move
bcc people onto a different header. I think that will bite someone when
it leaks information.

I would be happy with either empty headers or with the people staying
as bcc.

In the cc: case I have no preference (as those addresses are already
public) but I would suggest being consistent with bcc so either empty
headers or keep them in the cc line.

> for (messages = notmuch_query_search_messages (query);
> notmuch_messages_valid (messages);
> notmuch_messages_move_to_next (messages))
> {
[...]
>   (void)add_recipients_from_message (reply, config, message, reply_all);

Since the above logic is applied to each email individually I think
working out the recipients when replying to multiple emails (e.g.,
reply-to-sender on a thread) could be very confusing. Some of the people
being replied to will have been senders, some recipients (it is very
likely that the thread contains messages we sent), some could even be
cc, bcc people. Personally, I would have no idea what to expect from
reply-to-sender in this case.

(My personal choice would be not to allow notmuch-reply-to-sender if
multiple messages are specified. But I can obtain that by unbinding "r"
in the notmuch-search-mode-map keymap.)

Best wishes

Mark

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


Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jameson Graef Rollins
On Sun, 8 Jan 2012 15:01:30 -0700, Jeremy Nickurak  
wrote:
> FWIW, I generally prefer reply-all as the default. In my experience,
> when a message is sent to a bunch of people, it's usually treated as a
> "forum" discussion where everybody wants to be in on everything. Also,
> once you've started composing, it's much easier to delete people you
> don't want included than to add people who are no longer referenced in
> the new buffer at all.

That's a good point.  I think that maybe people are wanting to protect
against the accidental reply to all when you only mean to reply to the
sender.

jamie.


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


Re: [PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jeremy Nickurak
On Sun, Jan 8, 2012 at 16:32, Jameson Graef Rollins
 wrote:
> That's a good point.  I think that maybe people are wanting to protect
> against the accidental reply to all when you only mean to reply to the
> sender.

Certainly a worthy cause. All I'm saying is I make the mistake in the
other direction more frequently ;)
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] emacs: call "notmuch tag" only once when archiving a thread

2012-01-08 Thread Aaron Ecay
On Thu, 05 Jan 2012 22:32:16 +0200, Jani Nikula  wrote:

[...]

> In the show view it only modifies the messages that are currently
> visible. This is to make sure you don't accidentally archive things that
> have arrived after refreshing the buffer. I think this is safest.

Hmm.  Perhaps it would make sense to add a check in the search view that
the thread being archived[1] has the same number of messages as it did
when the buffer was constructed.  (The information on how many messages
the thread has is in the buffer; we would then compare this to the result
of “notmuch count thread:000foo” when the user requests to archive.)  If
the counts don’t match, the interface should show a message in the echo
area and (probably) refuse to do the tagging.

We could also optionally use this strategy in the search view too.  The
error message is simple there: “New messages have arrived; refresh
thread view before archiving.”  (It doesn’t make as much sense to tell
people to refresh a search view – it could be an expensive operation
and/or may not be idempotent if some thread’s tags have been changed.
So it’s harder to say what the advice should be in that case.)

If other people think it would be useful, I can work on a patch to
implement this approach.

Footnotes:
[1] Or having its tags changed generally.

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


Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging

2012-01-08 Thread Aaron Ecay
Jameson,

Some comments below:

On Sat,  7 Jan 2012 14:28:12 -0800, Jameson Graef Rollins 
 wrote:
> Instead of having a function that is only used for archiving a thread,
> we instead make it useful for any tagging operation.  The new
> function, notmuch-show-tag-thread-internal, now takes two more
> arguments, for the "sign" of the tagging operation ("-" or "+"), and
> the tag to be added or removed.  This will allow this function to be
> used for any generic thread tagging operation.
> 
> The higher level functions that call this function are modified
> accordingly.
> ---
>  emacs/notmuch-show.el |   34 --
>  1 files changed, 20 insertions(+), 14 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 5502efd..1e16f05 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -1414,20 +1414,26 @@ argument, hide all of the messages."
>(interactive)
>(backward-button 1))
>  
> -(defun notmuch-show-archive-thread-internal (show-next)
> +(defun notmuch-show-tag-thread-internal (sign tag show-next)

A couple of comments on the arguments:
- It would be good to make show-next &optional.  This will enable code
  to call the fn with only two arguments, and not showing next will be
  the default behavior.
- A more lispy way of specifying the sign would be to use a
  boolean.  Perhaps you could call this “remove”; a value of ‘t’ would
  remove the tag; ‘nil’ would add it.  Moving this argument after ‘tag’
  and also making it &optional woudl allow this fn to be called with one
  arg to add a tag.  (Maybe this is too minimalist and API, however.) 

>;; Remove the tag from the current set of messages.
>(goto-char (point-min))
> -  (loop do (notmuch-show-remove-tag "inbox")
> - until (not (notmuch-show-goto-message-next)))
> -  ;; Move to the next item in the search results, if any.
> -  (let ((parent-buffer notmuch-show-parent-buffer))
> -(notmuch-kill-this-buffer)
> -(if parent-buffer
> - (progn
> -   (switch-to-buffer parent-buffer)
> -   (forward-line)
> -   (if show-next
> -   (notmuch-search-show-thread))
> +  (let ((tag-function))

No second set of parens is needed around tag-function.

> +(cond
> + ((string= sign "-")
> +  (setq tag-function 'notmuch-show-remove-tag))
> + ((string= sign "+")
> +  (setq tag-function 'notmuch-show-add-tag)))
> +(loop do (funcall tag-function tag)
> +   until (not (notmuch-show-goto-message-next)))
> +;; Move to the next item in the search results, if any.

Does it make sense to separate the tagging and the movement?  It seems
plausible that some code somewhere might want to add/remove a tag from
all messages in the thread w/o changing the display.

> +(let ((parent-buffer notmuch-show-parent-buffer))
> +  (notmuch-kill-this-buffer)
> +  (if parent-buffer
> +   (progn
> + (switch-to-buffer parent-buffer)
> + (forward-line)
> + (if show-next
> + (notmuch-search-show-thread)))

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


Re: [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end

2012-01-08 Thread Aaron Ecay
Jameson,

One small, stylistic/nitpicky comment :)

On Sat,  7 Jan 2012 17:26:53 -0800, Jameson Graef Rollins 
 wrote:
> This will allow for keybindings that achieve a smoother message
> processing flow by reducing the number of key presses needed for most
> common operations.
> ---
>  emacs/notmuch-show.el |   12 +---
>  1 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 8bb052e..e7bb958 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -1264,17 +1264,23 @@ any effects from previous calls to
>(notmuch-show-mark-read)
>(notmuch-show-message-adjust))
>  
> -(defun notmuch-show-next-open-message ()
> +(defun notmuch-show-next-open-message (&optional pop-at-end)
>"Show the next message."
>(interactive)
> -  (let (r)
> +  (let ((r)
> + (parent-buffer notmuch-show-parent-buffer))

No second set of parentheses is needed around r.  Also, it is more
idiomatic to put the initialized variable (i.e. parent-buffer) before
the uninitialized one (r).

>  (while (and (setq r (notmuch-show-goto-message-next))
>   (not (notmuch-show-message-visible-p
>  (if r
>   (progn
> (notmuch-show-mark-read)
> (notmuch-show-message-adjust))
> -  (goto-char (point-max)
> +  (if (and parent-buffer pop-at-end)
> +   (progn
> + (kill-this-buffer)
> + (switch-to-buffer parent-buffer)
> + (forward-line 1))
> + (goto-char (point-max))
>  
>  (defun notmuch-show-previous-open-message ()
>"Show the previous message."
> -- 
> 1.7.7.3
> 
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

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


Re: [PATCH] emacs: call "notmuch tag" only once when archiving a thread

2012-01-08 Thread Austin Clements
Quoth Aaron Ecay on Jan 08 at  7:56 pm:
> On Thu, 05 Jan 2012 22:32:16 +0200, Jani Nikula  wrote:
> 
> [...]
> 
> > In the show view it only modifies the messages that are currently
> > visible. This is to make sure you don't accidentally archive things that
> > have arrived after refreshing the buffer. I think this is safest.
> 
> Hmm.  Perhaps it would make sense to add a check in the search view that
> the thread being archived[1] has the same number of messages as it did
> when the buffer was constructed.  (The information on how many messages
> the thread has is in the buffer; we would then compare this to the result
> of “notmuch count thread:000foo” when the user requests to archive.)  If
> the counts don’t match, the interface should show a message in the echo
> area and (probably) refuse to do the tagging.

That sounds like a clever workaround.

There's been quite a bit of discussion on fixing this properly.  See,
for example
id:"CAH-f9WsPj=1Eu=g3soepjgctbfs6hrldlq18xmenj8az00y...@mail.gmail.com".
The gist is that we need to include message IDs (or document IDs) in
the search output and use these in tagging operations, rather than the
unstable thread:XXX queries.  Unfortunately, actually fixing this got
stalled since adding this information the text format is a fool's
errand (having been the fool, I can say this!), so we need to switch
Emacs over to using the JSON search format first.  However, once
that's done, it's a relatively simple change.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Aaron Ecay
Jameson,

One comment

On Sat,  7 Jan 2012 14:28:11 -0800, Jameson Graef Rollins 
 wrote:
> The new customization variable, notmuch-search-exclude-deleted, when
> set to t, will exclude any messages with the "deleted" tag from
> searches.
> 
> Additionally, specifying "tag:deleted" in the search directly will
> override the exclusion and will included deleted messages in the
> search results.
> ---
>  emacs/notmuch.el   |8 
>  test/emacs |   42 
> 
>  .../notmuch-search-tag-inbox-deleted-excluded  |   24 +++
>  3 files changed, 74 insertions(+), 0 deletions(-)
>  create mode 100644 
> test/emacs.expected-output/notmuch-search-tag-inbox-deleted-excluded
> 
> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> index fde2377..c519687 100644
> --- a/emacs/notmuch.el
> +++ b/emacs/notmuch.el
> @@ -905,6 +905,11 @@ PROMPT is the string to prompt with."
>(read-from-minibuffer prompt nil keymap nil
>   'notmuch-query-history nil nil
>  
> +(defcustom notmuch-search-exclude-deleted nil
> +  "Exclude deleted messages (with \"deleted\" tag) from search results."
> +  :group 'notmuch
> +  :type 'boolean)
> +
>  ;;;###autoload
>  (defun notmuch-search (query &optional oldest-first target-thread 
> target-line continuation)
>"Run \"notmuch search\" with the given query string and display results.
> @@ -927,6 +932,9 @@ The optional parameters are used as follows:
>  (set 'notmuch-search-target-thread target-thread)
>  (set 'notmuch-search-target-line target-line)
>  (set 'notmuch-search-continuation continuation)
> +(when (and notmuch-search-exclude-deleted
> +(not (string-match "tag:deleted[ )]*" query)))

“is:” is a synonym for “tag:” in searches – so this section of the code
should look for it too.

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


Re: [PATCH 4/4] emacs: Use the new JSON reply format.

2012-01-08 Thread Aaron Ecay
Adam,

One comment below.

On Sun,  8 Jan 2012 00:52:42 -0700, Adam Wolfe Gordon  
wrote:
> From: Adam Wolfe Gordon 
> 
> Using the new JSON reply format allows emacs to quote HTML parts
> nicely by first parsing them with w3m, then quoting them. This is
> very useful for users who regularly receive HTML-only email.
> 
> The behavior for messages that contain plain text parts should be
> unchanged, except that an additional quoted line is added to the end
> of the reply message.  The test has been updated to reflect this.
> ---
>  emacs/notmuch-mua.el |   62 +++--
>  test/emacs   |1 +
>  2 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
> index 7114e48..7f894cb 100644
> --- a/emacs/notmuch-mua.el
> +++ b/emacs/notmuch-mua.el
> @@ -19,6 +19,7 @@
>  ;;
>  ;; Authors: David Edmondson 
>  
> +(require 'json)
>  (require 'message)
>  
>  (require 'notmuch-lib)
> @@ -71,27 +72,62 @@ list."
>   (push header message-hidden-headers)))
>   notmuch-mua-hidden-headers))
>  
> +(defun w3m-region (start end)) ;; From `w3m.el'.

What is the purpose of the above line?  If it is to make the compiler
aware of the function, you should use ‘declare-function’ instead.  Defun
will erase the original definition of the w3m-region function.

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


Re: [PATCH 0/4] Quoting HTML-only emails in replies redux

2012-01-08 Thread Aaron Ecay
On Sun,  8 Jan 2012 00:52:38 -0700, Adam Wolfe Gordon  
wrote:

[...]

> 
> There should probably be some customize variables for this in emacs, to 
> control
> (for example) whether to quote HTML parts and whether to prefer HTML or
> plaintext parts for quoting. Any suggestions for what should be customizable
> would be appreciated.

I think two variables should suffice: one (boolean) to control whether
to quote standalone text/html parts, and one to control which parts of a
multipart/alternative part to quote.  The latter should take possible
values 'text, 'html, and 'both.  This requires the emacs reply
functionality to distinguish between html parts that are part of a
multipart/alternative and those which are not, which (AFAICT) the
current code doesn’t do.

I haven’t tested the patch yet, but it looks very promising.  Thanks!

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


Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Austin Clements
> > @@ -927,6 +932,9 @@ The optional parameters are used as follows:
> >  (set 'notmuch-search-target-thread target-thread)
> >  (set 'notmuch-search-target-line target-line)
> >  (set 'notmuch-search-continuation continuation)
> > +(when (and notmuch-search-exclude-deleted
> > +  (not (string-match "tag:deleted[ )]*" query)))
> 
> “is:” is a synonym for “tag:” in searches – so this section of the code
> should look for it too.

There are several other things that could also trip up this regexp.
xtag:deletedx would be falsely matched, as would a quoted phrase
containing "tag:deleted", while tag:"deleted" and tag:(deleted) would
incorrectly not be matched.  Getting this right is hard, though I'd be
happy with

  "\\<\\(tag\\|is\\):deleted\\>"

or maybe

  "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2"

Implicit exclusions like this were actually one of my target features
for the custom query parser, but I think hacking around that by
inspecting the query string is a fine interim solution.  (One of these
months I'll dust off the query parser, really!)
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Jameson Graef Rollins
On Sun, 8 Jan 2012 20:49:38 -0500, Austin Clements  wrote:
> > > @@ -927,6 +932,9 @@ The optional parameters are used as follows:
> > >  (set 'notmuch-search-target-thread target-thread)
> > >  (set 'notmuch-search-target-line target-line)
> > >  (set 'notmuch-search-continuation continuation)
> > > +(when (and notmuch-search-exclude-deleted
> > > +(not (string-match "tag:deleted[ )]*" query)))
> > 
> > “is:” is a synonym for “tag:” in searches – so this section of the code
> > should look for it too.
> 
> There are several other things that could also trip up this regexp.
> xtag:deletedx would be falsely matched, as would a quoted phrase
> containing "tag:deleted", while tag:"deleted" and tag:(deleted) would
> incorrectly not be matched.

Thanks so much for the review, guys.  I should have mentioned in this
patch that the my regex skills are very weak, and that it was surely
incomplete.  I always forget about the is: prefix as well.

> Getting this right is hard, though I'd be happy with
> 
>   "\\<\\(tag\\|is\\):deleted\\>"

Every time I think I start to understand regex I am reminded that it's
black magic and I really know nothing.  For instance, I am not familiar
with "<" or ">", although they appear to be a "word" boundaries
(although I'm not sure how "word" is defined).  Also, why is all the \\
(double?)  escaping needed?  I'll certainly take your word for it,
though.

> or maybe
> 
>   "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2"

After staring at this for 10 minutes I think I'm getting the extra bits
here.  It matches an initial \", and then a second at the end if the
first matched.  That's clever.  Why 

  \\>\\2

instead of

 \\2\\>

?

I'm definitely confused by why so much apparent escaping is needed,
though.

> Implicit exclusions like this were actually one of my target features
> for the custom query parser, but I think hacking around that by
> inspecting the query string is a fine interim solution.  (One of these
> months I'll dust off the query parser, really!)

Very much looking forward to it!

jamie.


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


Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Austin Clements
Quoth Jameson Graef Rollins on Jan 08 at  6:34 pm:
> On Sun, 8 Jan 2012 20:49:38 -0500, Austin Clements  wrote:
> > > > @@ -927,6 +932,9 @@ The optional parameters are used as follows:
> > > >  (set 'notmuch-search-target-thread target-thread)
> > > >  (set 'notmuch-search-target-line target-line)
> > > >  (set 'notmuch-search-continuation continuation)
> > > > +(when (and notmuch-search-exclude-deleted
> > > > +  (not (string-match "tag:deleted[ )]*" query)))
> > > 
> > > “is:” is a synonym for “tag:” in searches – so this section of the code
> > > should look for it too.
> > 
> > There are several other things that could also trip up this regexp.
> > xtag:deletedx would be falsely matched, as would a quoted phrase
> > containing "tag:deleted", while tag:"deleted" and tag:(deleted) would
> > incorrectly not be matched.
> 
> Thanks so much for the review, guys.  I should have mentioned in this
> patch that the my regex skills are very weak, and that it was surely
> incomplete.  I always forget about the is: prefix as well.
> 
> > Getting this right is hard, though I'd be happy with
> > 
> >   "\\<\\(tag\\|is\\):deleted\\>"
> 
> Every time I think I start to understand regex I am reminded that it's
> black magic and I really know nothing.  For instance, I am not familiar
> with "<" or ">", although they appear to be a "word" boundaries
> (although I'm not sure how "word" is defined).  Also, why is all the \\
> (double?)  escaping needed?  I'll certainly take your word for it,
> though.

I'm not positive, but I think \> matches on the transition from a
"word-constituent" character to a non-word-constituent character, as
defined by Emacs' active syntax table.

The slashes are all doubled because I was writing it as an Emacs
string for easy pasting (sorry, I should have been explicit about
that).  The regexp itself is

  \<\(tag\|is\):deleted\>

> > or maybe
> > 
> >   "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2"
> 
> After staring at this for 10 minutes I think I'm getting the extra bits
> here.  It matches an initial \", and then a second at the end if the
> first matched.  That's clever.  Why 

Exactly.

>   \\>\\2
> 
> instead of
> 
>  \\2\\>
> 
> ?

Okay, that can qualify as black magic.  The problem is that a " will
mess up the word-boundary matching because " isn't a word constituent
character.  So, if it is looking for a quote at the end, the \2 in
\2\> would match and consume the ", but then the \> wouldn't match.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging

2012-01-08 Thread Jameson Graef Rollins
Thanks so much for the review, Aaron.

On Sun, 08 Jan 2012 20:08:59 -0500, Aaron Ecay  wrote:
> A couple of comments on the arguments:
> - It would be good to make show-next &optional.  This will enable code
>   to call the fn with only two arguments, and not showing next will be
>   the default behavior.

That's a nice idea.  Probably better for a separate patch, though.

> - A more lispy way of specifying the sign would be to use a
>   boolean.  Perhaps you could call this “remove”; a value of ‘t’ would
>   remove the tag; ‘nil’ would add it.  Moving this argument after ‘tag’
>   and also making it &optional woudl allow this fn to be called with one
>   arg to add a tag.  (Maybe this is too minimalist and API, however.) 

That might be more lispy, but it seems a lot less clear to me.  It might
save a few keystrokes when coding, but it would definitely make the code
a lot harder to read ("remove" to add a tag?).  I think I would prefer
people to give the sign explicitly.

> No second set of parens is needed around tag-function.

Yeah, I've seen this either way.  I guess it's just a stylistic choice.

I think it might make sense, but again I think that's out of the scope
of this patch series.  The point was to make a minimal set of
modifications here.  If we want to separate out the functionality, we
should do that in a separate patch.

Thanks again for the review.

jamie.


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


Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Austin Clements
Quoth myself on Jan 08 at  8:49 pm:
> > > @@ -927,6 +932,9 @@ The optional parameters are used as follows:
> > >  (set 'notmuch-search-target-thread target-thread)
> > >  (set 'notmuch-search-target-line target-line)
> > >  (set 'notmuch-search-continuation continuation)
> > > +(when (and notmuch-search-exclude-deleted
> > > +(not (string-match "tag:deleted[ )]*" query)))
> > 
> > “is:” is a synonym for “tag:” in searches – so this section of the code
> > should look for it too.
> 
> There are several other things that could also trip up this regexp.
> xtag:deletedx would be falsely matched, as would a quoted phrase
> containing "tag:deleted", while tag:"deleted" and tag:(deleted) would
> incorrectly not be matched.  Getting this right is hard, though I'd be
> happy with
> 
>   "\\<\\(tag\\|is\\):deleted\\>"
> 
> or maybe
> 
>   "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2"

For the record, here's a More Correct (TM) version

  "\\(^\\|[-+ ()]\\)\\(tag\\|is\\):\\(\"?\\)deleted\\3\\($\\|[ ()]\\)"

However, as we discussed on IRC, it's probably better to fix this in
the CLI/library by adding a config option for auto-excluded tags, an
API to register these with the library (probably part of the query
API), and to iterate over the terms in the parsed query to determine
which tag exclusions should be automatically added.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging

2012-01-08 Thread Aaron Ecay
On Sun, 08 Jan 2012 18:49:56 -0800, Jameson Graef Rollins 
 wrote:
> Thanks so much for the review, Aaron.
> 
> On Sun, 08 Jan 2012 20:08:59 -0500, Aaron Ecay  wrote:
> > A couple of comments on the arguments:
> > - It would be good to make show-next &optional.  This will enable code
> >   to call the fn with only two arguments, and not showing next will be
> >   the default behavior.
> 
> That's a nice idea.  Probably better for a separate patch, though.

This patch introduces show-next as a new argument to the function.  So it
can and should make it &optional, if that is the appropriate semantics
for it to have.

> 
> > - A more lispy way of specifying the sign would be to use a
> >   boolean.  Perhaps you could call this “remove”; a value of ‘t’ would
> >   remove the tag; ‘nil’ would add it.  Moving this argument after ‘tag’
> >   and also making it &optional woudl allow this fn to be called with one
> >   arg to add a tag.  (Maybe this is too minimalist and API, however.) 
> 
> That might be more lispy, but it seems a lot less clear to me.  It might
> save a few keystrokes when coding, but it would definitely make the code
> a lot harder to read ("remove" to add a tag?).  I think I would prefer
> people to give the sign explicitly.

Using a string value makes it harder to interface with other code.  For
example, the prefix argument (C-u) is delivered to emacs commands as a
boolean value (nil if no arg, something truthy if the arg is given).  A
plausible custom end user function/keybinding would be one to add a tag
to the open messages, or remove that tag if the prefix arg is given to
the same command.  (So that ‘d’ deletes and ‘C-u d’ undeletes, for
example.)  In order to do that, the user’s code has to convert the
prefix arg into a string.  Making something “lispy” isn’t just about
code readability/saving keystrokes, but also refers to how well the
code interfaces with the conventions used by the rest of the emacs
environment.

That said, here’s an alternate proposal: provide two functions as the
“external” API, namely ‘notmuch-show-{add,remove}-tag-thread’ (by
parallelism with ‘notmuch-show-{add,remove}-tag’).  These could be
thin wrappers around ‘notmuch-show-tag-thread-internal’, which would
then not be intended to be called by user code.

> 
> > No second set of parens is needed around tag-function.
> 
> Yeah, I've seen this either way.  I guess it's just a stylistic
> choice.

Using double parens is semantically correct, but makes the code less
idiomatic and harder to read (IMO).  To test my intuition, I looked at
‘let’ invocations in the Emacs source that have a non-initialized
variable (because the multiple variable case is hard to grep for).
Double parens are used only 3% of the time (44 double vs 1468 single).
Make of this data what you will.

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


Re: notmuch git's disk is full! ERROR pushing.

2012-01-08 Thread Carl Worth
On Sun, 08 Jan 2012 13:55:53 +0100, Sebastian Spaeth  
wrote:
> Actually trying to push the above 2 patches, I get 
> 
> Writing objects: 100% (8/8), 1.25 KiB, done.
> Total 8 (delta 5), reused 0 (delta 0)
> error: unable to create temporary sha1 filename : No space left on
> device

My apologies!

I've relieved the immediate problem for now. (And I'm hoping to soon
move notmuchmail.org to a different server with a disk that's a couple
of orders of magnitude larger.)

-Carl


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


Re: Python bindings for adoption

2012-01-08 Thread sebast...@sspaeth.de
Hurray, thanks Justus. That is much appreciated.
Spaetz



David Bremner  schrieb:

>On Sun, 08 Jan 2012 16:16:06 -, Justus Winter
><4win...@informatik.uni-hamburg.de> wrote:
>> 
>> I've decided to step up as a new maintainer for the libnotmuch python
>> bindings. I assume that I'll have to mail an ssh public key to
>someone
>> for repository access, right?
>> 
>
>That's right. Carl (in copy) handles repository access.
>
>d

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


[RFC PATCH 0/9] -std=c99 / -std=c++0x -pedantic

2012-01-08 Thread Jani Nikula
Hi all, this series was borne of curiousity about compiling the notmuch codebase
using -std=c99 / -std=c++0x -pedantic options. The C part is split into separate
patches to make it easier to see each warning and fix; with C++ I didn't bother
so much.

Turns out there are a few specific issues, but overall it's not too bad. However
my gut feeling is that some of the fixes to get standards compliance are uglier
than just using the GCC extensions. The question is, do we care about anything
other than GCC?

Comments and discussion welcome; that was the whole point here rather than any
serious effort for merging these. (But that can follow if people think this is
worth it.)

BR,
Jani.



Jani Nikula (9):
  build: use -std=c99 -pedantic for C source
  xutil: #define _POSIX_C_SOURCE to get strdup()
  lib: fix messages.c build warn
  lib: HACK: avoid warnings from talloc_steal()
  cli: fix warning about variadic macros
  cli: fix another warning about variadic macros
  util: fix warning about variadic macros
  lib: use -std=c++0x -pedantic
  test: smtp-dummy: fixes for -std=c99 -pedantic

 configure |4 ++--
 lib/database.cc   |3 +--
 lib/message.cc|2 +-
 lib/messages.c|6 --
 lib/notmuch-private.h |8 +---
 lib/tags.c|5 -
 lib/thread.cc |2 +-
 notmuch-client.h  |9 ++---
 notmuch-setup.c   |7 +--
 test/smtp-dummy.c |4 +++-
 util/error_util.h |8 +---
 util/xutil.c  |2 ++
 12 files changed, 39 insertions(+), 21 deletions(-)

-- 
1.7.5.4



[RFC PATCH 1/9] build: use -std=c99 -pedantic for C source

2012-01-08 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 configure |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index e90b76f..f84262d 100755
--- a/configure
+++ b/configure
@@ -25,8 +25,8 @@ fi
 # environment variables)
 CC=${CC:-gcc}
 CXX=${CXX:-g++}
-CFLAGS=${CFLAGS:--O2}
-CXXFLAGS=${CXXFLAGS:-\$(CFLAGS)}
+CFLAGS=${CFLAGS:--O2 -std=c99 -pedantic}
+CXXFLAGS=${CXXFLAGS:--O2}
 LDFLAGS=${LDFLAGS:-}
 XAPIAN_CONFIG=${XAPIAN_CONFIG:-xapian-config}

-- 
1.7.5.4



[RFC PATCH 2/9] xutil: #define _POSIX_C_SOURCE to get strdup()

2012-01-08 Thread Jani Nikula
strdup() is not standard C99. #define _POSIX_C_SOURCE 200809L to use it.

This fixes -std=c99 -pedantic warning:

util/xutil.c: In function ?xstrdup?:
util/xutil.c:74:5: warning: implicit declaration of function ?strdup? 
[-Wimplicit-function-declaration]
util/xutil.c:74:9: warning: assignment makes pointer from integer without a 
cast [enabled by default]

Signed-off-by: Jani Nikula 
---
 util/xutil.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/util/xutil.c b/util/xutil.c
index ac496da..55b818b 100644
--- a/util/xutil.c
+++ b/util/xutil.c
@@ -18,6 +18,8 @@
  * Author: Carl Worth 
  */

+#define _POSIX_C_SOURCE 200809L /* for strdup() */
+
 #include 
 #include 

-- 
1.7.5.4



[RFC PATCH 4/9] lib: HACK: avoid warnings from talloc_steal()

2012-01-08 Thread Jani Nikula
talloc.h #defines talloc_steal() with macros to make it type safe, but
introduces a warning when compiled using -std=c99 -pedantic:

lib/tags.c: In function ?_notmuch_tags_create?:
lib/tags.c:43:5: warning: ISO C forbids braced-groups within expressions 
[-pedantic]

Call _talloc_steal_loc() directly without the macro wrapper. We aren't even
interested in the return value the macro is so hard trying to provide type
safety for.

Signed-off-by: Jani Nikula 
---
 lib/tags.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/lib/tags.c b/lib/tags.c
index c58924f..56c43e2 100644
--- a/lib/tags.c
+++ b/lib/tags.c
@@ -40,7 +40,10 @@ _notmuch_tags_create (const void *ctx, notmuch_string_list_t 
*list)
return NULL;

 tags->iterator = list->head;
-talloc_steal (tags, list);
+
+/* _talloc_steal_loc() is talloc_steal() without macro wrapping to avoid
+ * -std=c99 -pedantic warning. __location__ is defined in talloc.h. */
+_talloc_steal_loc (tags, list, __location__);

 return tags;
 }
-- 
1.7.5.4



[RFC PATCH 3/9] lib: fix messages.c build warn

2012-01-08 Thread Jani Nikula
lib/messages.c: In function ?notmuch_messages_move_to_next?:
lib/messages.c:131:2: warning: ISO C forbids ?return? with expression, in 
function returning void [-pedantic]

Signed-off-by: Jani Nikula 
---
 lib/messages.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/messages.c b/lib/messages.c
index 7bcd1ab..1121864 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -127,8 +127,10 @@ notmuch_messages_get (notmuch_messages_t *messages)
 void
 notmuch_messages_move_to_next (notmuch_messages_t *messages)
 {
-if (! messages->is_of_list_type)
-   return _notmuch_mset_messages_move_to_next (messages);
+if (! messages->is_of_list_type) {
+   _notmuch_mset_messages_move_to_next (messages);
+   return;
+}

 if (messages->iterator == NULL)
return;
-- 
1.7.5.4



[RFC PATCH 5/9] cli: fix warning about variadic macros

2012-01-08 Thread Jani Nikula
notmuch-restore.c: In function ?notmuch_restore_command?:
notmuch-restore.c:87:54: warning: ISO C99 requires rest arguments to be used 
[enabled by default]

and elsewhere. ##__VA_ARGS__ is a GCC CPP extension.

Signed-off-by: Jani Nikula 
---
 notmuch-client.h |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index 517c010..3f4751a 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -93,14 +93,17 @@ typedef struct notmuch_show_params {
  *
  * Note that __location__ comes from talloc.h.
  */
-#define INTERNAL_ERROR(format, ...)\
+
+#define _INTERNAL_ERROR(format, ...)   \
 do {   \
fprintf(stderr, \
-   "Internal error: " format " (%s)\n",\
-   ##__VA_ARGS__, __location__);   \
+   "Internal error: " format "%s (%s)\n",  \
+   __VA_ARGS__, __location__); \
exit (1);   \
 } while (0)

+#define INTERNAL_ERROR(...) _INTERNAL_ERROR(__VA_ARGS__, "")
+
 #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))

 #define STRNCMP_LITERAL(var, literal) \
-- 
1.7.5.4



[RFC PATCH 6/9] cli: fix another warning about variadic macros

2012-01-08 Thread Jani Nikula
notmuch-setup.c: In function ?notmuch_setup_command?:
notmuch-setup.c:144:62: warning: ISO C99 requires rest arguments to be used 
[enabled by default]
notmuch-setup.c:174:18: warning: ISO C99 requires rest arguments to be used 
[enabled by default]

Signed-off-by: Jani Nikula 
---
 notmuch-setup.c |7 +--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/notmuch-setup.c b/notmuch-setup.c
index c3ea937..7b25680 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -102,9 +102,9 @@ notmuch_setup_command (unused (void *ctx),
 const char **new_tags;
 size_t new_tags_len;

-#define prompt(format, ...)\
+#define __prompt(format, ...)  \
 do {   \
-   printf (format, ##__VA_ARGS__); \
+   printf (format, __VA_ARGS__);   \
fflush (stdout);\
if (getline (&response, &response_size, stdin) < 0) {   \
printf ("Exiting.\n");  \
@@ -113,6 +113,9 @@ notmuch_setup_command (unused (void *ctx),
chomp_newline (response);   \
 } while (0)

+#define _prompt(format, ...) __prompt(format "%s", __VA_ARGS__)
+#define prompt(...) _prompt(__VA_ARGS__, "")
+
 config = notmuch_config_open (ctx, NULL, &is_new);

 if (is_new)
-- 
1.7.5.4



[RFC PATCH 7/9] util: fix warning about variadic macros

2012-01-08 Thread Jani Nikula
lib/string-list.c: In function ?_notmuch_string_list_sort?:
lib/string-list.c:81:59: warning: ISO C99 requires rest arguments to be used 
[enabled by default]

lib/message-file.c: In function ?notmuch_message_file_restrict_headersv?:
lib/message-file.c:147:90: warning: ISO C99 requires rest arguments to be used 
[enabled by default]

Signed-off-by: Jani Nikula 
---
 util/error_util.h |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/util/error_util.h b/util/error_util.h
index bb15822..75709da 100644
--- a/util/error_util.h
+++ b/util/error_util.h
@@ -38,8 +38,10 @@ _internal_error (const char *format, ...) PRINTF_ATTRIBUTE 
(1, 2);
  *
  * Note that __location__ comes from talloc.h.
  */
-#define INTERNAL_ERROR(format, ...)\
-_internal_error (format " (%s).\n",\
-##__VA_ARGS__, __location__)
+#define _INTERNAL_ERROR(format, ...)   \
+_internal_error (format "%s (%s).\n",  \
+__VA_ARGS__, __location__)
+
+#define INTERNAL_ERROR(...) _INTERNAL_ERROR(__VA_ARGS__, "")

 #endif
-- 
1.7.5.4



[RFC PATCH 9/9] test: smtp-dummy: fixes for -std=c99 -pedantic

2012-01-08 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 test/smtp-dummy.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/test/smtp-dummy.c b/test/smtp-dummy.c
index 3801a5e..1c29a7d 100644
--- a/test/smtp-dummy.c
+++ b/test/smtp-dummy.c
@@ -33,6 +33,8 @@
  * have been warned.
  */

+#define _POSIX_C_SOURCE 200809L /* for getline() and fdopen() */
+
 #include 
 #include 
 #include 
@@ -162,7 +164,7 @@ main (int argc, char *argv[])
memset (&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_port = htons (25025);
-   addr.sin_addr = *(struct in_addr *) hostinfo->h_addr;
+   addr.sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0];
err = bind (sock, (struct sockaddr *) &addr, sizeof(addr));
if (err) {
fprintf (stderr, "Error: bind() failed: %s\n",
-- 
1.7.5.4



[RFC PATCH 8/9] lib: use -std=c++0x -pedantic

2012-01-08 Thread Jani Nikula
Introduces warnings such as:

In file included from /usr/include/gmime-2.4/gmime/gmime.h:39:0,
 from lib/database.cc:31:
/usr/include/gmime-2.4/gmime/gmime-message.h:57:26: warning: comma at end of 
enumerator list [-pedantic]

Signed-off-by: Jani Nikula 
---
 configure |2 +-
 lib/database.cc   |3 +--
 lib/message.cc|2 +-
 lib/notmuch-private.h |8 +---
 lib/thread.cc |2 +-
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/configure b/configure
index f84262d..30831f3 100755
--- a/configure
+++ b/configure
@@ -26,7 +26,7 @@ fi
 CC=${CC:-gcc}
 CXX=${CXX:-g++}
 CFLAGS=${CFLAGS:--O2 -std=c99 -pedantic}
-CXXFLAGS=${CXXFLAGS:--O2}
+CXXFLAGS=${CXXFLAGS:--O2 -std=c++0x -pedantic}
 LDFLAGS=${LDFLAGS:-}
 XAPIAN_CONFIG=${XAPIAN_CONFIG:-xapian-config}

diff --git a/lib/database.cc b/lib/database.cc
index 8103bd9..b59497b 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -1352,8 +1352,7 @@ _resolve_message_id_to_thread_id (notmuch_database_t 
*notmuch,
return status;

 if (message) {
-   *thread_id_ret = talloc_steal (ctx,
-  notmuch_message_get_thread_id (message));
+   *thread_id_ret = (const char *) _talloc_steal_loc (ctx, 
notmuch_message_get_thread_id (message), __location__);

notmuch_message_destroy (message);

diff --git a/lib/message.cc b/lib/message.cc
index 0075425..ed7398a 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -220,7 +220,7 @@ _notmuch_message_create_for_message_id (notmuch_database_t 
*notmuch,

message_id,

&message);
 if (message)
-   return talloc_steal (notmuch, message);
+   return (notmuch_message_t *) _talloc_steal_loc (notmuch, message, 
__location__);
 else if (*status_ret)
return NULL;

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 60a932f..7694705 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -137,15 +137,17 @@ typedef enum _notmuch_private_status {
  * that the caller has previously handled any expected
  * notmuch_private_status_t values.)
  */
-#define COERCE_STATUS(private_status, format, ...) \
+#define _COERCE_STATUS(private_status, format, ...)\
 ((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS)\
  ? \
- (notmuch_status_t) _internal_error (format " (%s).\n",\
- ##__VA_ARGS__,
\
+ (notmuch_status_t) _internal_error (format "%s (%s).\n",  \
+ __VA_ARGS__,  \
  __location__) \
  : \
  (notmuch_status_t) private_status)

+#define COERCE_STATUS(private_status, ...) _COERCE_STATUS(private_status, 
__VA_ARGS__, "")
+
 typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;

 /* database.cc */
diff --git a/lib/thread.cc b/lib/thread.cc
index 0435ee6..e8f169c 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -224,7 +224,7 @@ _thread_add_message (notmuch_thread_t *thread,
 char *clean_author;

 _notmuch_message_list_add_message (thread->message_list,
-  talloc_steal (thread, message));
+  (notmuch_message_t *) _talloc_steal_loc 
(thread, message, __location__));
 thread->total_messages++;

 g_hash_table_insert (thread->message_hash,
-- 
1.7.5.4



[PATCH 0/4] Quoting HTML-only emails in replies redux

2012-01-08 Thread Adam Wolfe Gordon
From: Adam Wolfe Gordon 

Hi everyone,

This is a rework of my previous patch series adding support for replying to HTML
email in the emacs interface
(id:1322671241-23438-1-git-send-email-awg+notmuch at xvx.ca).

It was suggested on IRC that a more general solution would be to add a JSON
format to notmuch reply, and then have the emacs client parse the JSON to create
an appropriate reply. This patchset implements that.

The previous patches had an issue with emails that contained both HTML and
plaintext parts, where all the parts would end up quoted. This version avoids
that problem, since the emacs interface can easily check whether there are
plaintext parts and avoid quoting HTML parts if there are.

There should probably be some customize variables for this in emacs, to control
(for example) whether to quote HTML parts and whether to prefer HTML or
plaintext parts for quoting. Any suggestions for what should be customizable
would be appreciated.

I know Jani is currently working on some reply-related patches (the reply-all
vs. reply-one set). These changes probably won't merge cleanly with those
changes, so some care might be required. If his changes are pushed first, I'll
happily rebase and send a new set.

Thanks in advance for any reviews.

Adam Wolfe Gordon (4):
  test: Add broken test for the new JSON reply format.
  reply: Add a JSON reply format.
  man: Update notmuch-reply man page for JSON format.
  emacs: Use the new JSON reply format.

 emacs/notmuch-mua.el |   62 +---
 man/man1/notmuch-reply.1 |5 +
 notmuch-reply.c  |  269 +++---
 test/emacs   |1 +
 test/multipart   |7 ++
 5 files changed, 292 insertions(+), 52 deletions(-)

-- 
1.7.5.4



[PATCH 1/4] test: Add broken test for the new JSON reply format.

2012-01-08 Thread Adam Wolfe Gordon
From: Adam Wolfe Gordon 

---
 test/multipart |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/test/multipart b/test/multipart
index f83526b..f5ebf04 100755
--- a/test/multipart
+++ b/test/multipart
@@ -589,6 +589,13 @@ Non-text part: text/html
 EOF
 test_expect_equal_file OUTPUT EXPECTED

+test_begin_subtest "'notmuch reply' to a multipart message with json format"
+notmuch reply --format=json 'id:87liy5ap00.fsf at yoom.home.cworth.org' >OUTPUT
+cat ", "references": " <87liy5ap00.fsf at 
yoom.home.cworth.org>"} }, "original": { "headers": { "from": "Carl Worth 
", "to": "cworth at cworth.org", "cc": "", "subject": 
"Multipart message", "date": "Fri, 05 Jan 2001 15:43:57 +", "in-reply-to": 
"", "references": "" }, "body": [ { "content-type": "text/html", "content": 
"This is an embedded message, with a multipart/alternative part.\n"}, { 
"content-type": "text/plain", "content": "This is an embedded message, with a 
multipart/alternative part.\n"}, { "content-type": "text/plain", "content": 
"And this message is signed.\n\n-Carl\n"}, {} ] } }, {} ]
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
 test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF 
pair"
 notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out
 echo -n -e "\xEF\x0D\x0A" > crlf.expected
-- 
1.7.5.4



[PATCH 3/4] man: Update notmuch-reply man page for JSON format.

2012-01-08 Thread Adam Wolfe Gordon
From: Adam Wolfe Gordon 

---
 man/man1/notmuch-reply.1 |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 099d808..240dfed 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -41,6 +41,11 @@ include
 .BR default
 Includes subject and quoted message body.
 .TP
+.BR json
+Produces JSON output containing headers for a reply message and the
+headers and text parts of the original message. This output can be used
+by a client to create a reply message intelligently.
+.TP
 .BR headers\-only
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
-- 
1.7.5.4



[PATCH 2/4] reply: Add a JSON reply format.

2012-01-08 Thread Adam Wolfe Gordon
From: Adam Wolfe Gordon 

This new JSON format for replies includes headers generated for a reply
message as well as the headers and all text parts of the original message.
Using this data, a client can intelligently create a reply. For example,
the emacs client will be able to create replies with quoted HTML parts by
parsing the HTML parts using w3m.
---
 notmuch-reply.c |  269 +++
 1 files changed, 230 insertions(+), 39 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index f8d5f64..82df396 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -30,6 +30,15 @@ reply_headers_message_part (GMimeMessage *message);
 static void
 reply_part_content (GMimeObject *part);

+static void
+reply_part_start_json (GMimeObject *part, int *part_count);
+
+static void
+reply_part_content_json (GMimeObject *part);
+
+static void
+reply_part_end_json (GMimeObject *part);
+
 static const notmuch_show_format_t format_reply = {
 "",
"", NULL,
@@ -46,6 +55,22 @@ static const notmuch_show_format_t format_reply = {
 ""
 };

+static const notmuch_show_format_t format_json = {
+"",
+   "", NULL,
+   "", NULL, NULL, "",
+   "",
+   reply_part_start_json,
+   NULL,
+   NULL,
+   reply_part_content_json,
+   reply_part_end_json,
+   "",
+   "",
+   "", "",
+""
+};
+
 static void
 show_reply_headers (GMimeMessage *message)
 {
@@ -147,6 +172,78 @@ reply_part_content (GMimeObject *part)
 }
 }

+static void
+reply_part_start_json (GMimeObject *part, unused(int *part_count))
+{
+GMimeContentType *content_type = g_mime_object_get_content_type 
(GMIME_OBJECT (part));
+GMimeContentDisposition *disposition = 
g_mime_object_get_content_disposition (part);
+
+if (g_mime_content_type_is_type (content_type, "text", "*") &&
+   (!disposition ||
+strcmp (disposition->disposition, GMIME_DISPOSITION_INLINE) == 0))
+{
+   printf("{ ");
+}
+}
+
+static void
+reply_part_end_json (GMimeObject *part)
+{
+GMimeContentType *content_type = g_mime_object_get_content_type 
(GMIME_OBJECT (part));
+GMimeContentDisposition *disposition = 
g_mime_object_get_content_disposition (part);
+
+if (g_mime_content_type_is_type (content_type, "text", "*") &&
+   (!disposition ||
+strcmp (disposition->disposition, GMIME_DISPOSITION_INLINE) == 0))
+   printf ("}, ");
+}
+
+static void
+reply_part_content_json (GMimeObject *part)
+{
+GMimeContentType *content_type = g_mime_object_get_content_type 
(GMIME_OBJECT (part));
+GMimeContentDisposition *disposition = 
g_mime_object_get_content_disposition (part);
+
+void *ctx = talloc_new (NULL);
+
+/* We only care about inline text parts for reply purposes */
+if (g_mime_content_type_is_type (content_type, "text", "*") &&
+   (!disposition ||
+strcmp (disposition->disposition, GMIME_DISPOSITION_INLINE) == 0))
+{
+   GMimeStream *stream_memory = NULL, *stream_filter = NULL;
+   GMimeDataWrapper *wrapper;
+   GByteArray *part_content;
+   const char *charset;
+
+   printf("\"content-type\": %s, \"content\": ",
+  json_quote_str(ctx, 
g_mime_content_type_to_string(content_type)));
+
+   charset = g_mime_object_get_content_type_parameter (part, "charset");
+   stream_memory = g_mime_stream_mem_new ();
+   if (stream_memory) {
+   stream_filter = g_mime_stream_filter_new(stream_memory);
+   if (charset) {
+   g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),
+g_mime_filter_charset_new(charset, 
"UTF-8"));
+   }
+   }
+   wrapper = g_mime_part_get_content_object (GMIME_PART (part));
+   if (wrapper && stream_filter)
+   g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);
+   part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM 
(stream_memory));
+
+   printf("%s", json_quote_chararray(ctx, (char *) part_content->data, 
part_content->len));
+
+   if (stream_filter)
+   g_object_unref(stream_filter);
+   if (stream_memory)
+   g_object_unref(stream_memory);
+}
+
+talloc_free (ctx);
+}
+
 /* Is the given address configured as one of the user's "personal" or
  * "other" addresses. */
 static int
@@ -476,6 +573,59 @@ guess_from_received_header (notmuch_config_t *config, 
notmuch_message_t *message
 return NULL;
 }

+static GMimeMessage *
+create_reply_message(void *ctx,
+notmuch_config_t *config,
+notmuch_message_t *message)
+{
+const char *subject, *from_addr = NULL;
+const char *in_reply_to, *orig_references, *references;
+
+/* The 1 means we want headers in a "pretty" order. */
+GMimeMessage *reply = g_mime_message_new (1);
+if (reply == NULL) {
+   fprintf (stderr, "Out of

[PATCH 4/4] emacs: Use the new JSON reply format.

2012-01-08 Thread Adam Wolfe Gordon
From: Adam Wolfe Gordon 

Using the new JSON reply format allows emacs to quote HTML parts
nicely by first parsing them with w3m, then quoting them. This is
very useful for users who regularly receive HTML-only email.

The behavior for messages that contain plain text parts should be
unchanged, except that an additional quoted line is added to the end
of the reply message.  The test has been updated to reflect this.
---
 emacs/notmuch-mua.el |   62 +++--
 test/emacs   |1 +
 2 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7114e48..7f894cb 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -19,6 +19,7 @@
 ;;
 ;; Authors: David Edmondson 

+(require 'json)
 (require 'message)

 (require 'notmuch-lib)
@@ -71,27 +72,62 @@ list."
(push header message-hidden-headers)))
notmuch-mua-hidden-headers))

+(defun w3m-region (start end)) ;; From `w3m.el'.
+(defun notmuch-mua-quote-part (part)
+  (with-temp-buffer
+(insert part)
+(message-mode)
+(fill-region (point-min) (point-max))
+(goto-char (point-min))
+(perform-replace "^" "> " nil t nil)
+(set-buffer-modified-p nil)
+(buffer-substring (point-min) (point-max
+(defun notmuch-mua-parse-html-part (part)
+  (with-temp-buffer
+(insert part)
+(w3m-region (point-min) (point-max))
+(set-buffer-modified-p nil)
+(buffer-substring (point-min) (point-max
 (defun notmuch-mua-reply (query-string &optional sender)
-  (let (headers
+  (let (reply
+   original
+   headers
body
-   (args '("reply")))
+   (args '("reply" "--format=json")))
 (if notmuch-show-process-crypto
(setq args (append args '("--decrypt"
 (setq args (append args (list query-string)))
-;; This make assumptions about the output of `notmuch reply', but
-;; really only that the headers come first followed by a blank
-;; line and then the body.
+;; Get the reply object as JSON, and parse it into an elisp object.
 (with-temp-buffer
   (apply 'call-process (append (list notmuch-command nil (list t t) nil) 
args))
   (goto-char (point-min))
-  (if (re-search-forward "^$" nil t)
- (save-excursion
-   (save-restriction
- (narrow-to-region (point-min) (point))
- (goto-char (point-min))
- (setq headers (mail-header-extract)
-  (forward-line 1)
-  (setq body (buffer-substring (point) (point-max
+  (setq reply (aref (json-read) 0)))
+
+;; Get the list of headers
+(setq headers (cdr (assq 'headers (assq 'reply reply
+;; Construct the body of the reply.
+(setq original (cdr (assq 'original reply)))
+
+;; Start with the prelude, based on the headers of the original message.
+(let ((original-headers (cdr (assq 'headers original
+  (setq body (format "On %s, %s wrote:\n"
+(cdr (assq 'date original-headers))
+(cdr (assq 'from original-headers)
+
+;; Extract the body parts and construct a reasonable quoted body.
+(let* ((body-parts (cdr (assq 'body original)))
+  (find-parts (lambda (type) (delq nil (mapcar (lambda (part)
+ (if (string= (cdr 
(assq 'content-type part)) type)
+ (cdr (assq 
'content part
+   body-parts
+  (plain-parts (apply find-parts '("text/plain")))
+  (html-parts (apply find-parts '("text/html"
+  
+  (if (not (null plain-parts))
+ (mapc (lambda (part) (setq body (concat body (notmuch-mua-quote-part 
part plain-parts)
+   (mapc (lambda (part) (setq body (concat body (notmuch-mua-quote-part 
(notmuch-mua-parse-html-part part) html-parts)))
+(setq body (concat body "\n"))
+   
 ;; If sender is non-nil, set the From: header to its value.
 (when sender
   (mail-header-set 'from sender headers))
diff --git a/test/emacs b/test/emacs
index a06c223..fe501da 100755
--- a/test/emacs
+++ b/test/emacs
@@ -270,6 +270,7 @@ Fcc: $(pwd)/mail/sent
 --text follows this line--
 On 01 Jan 2000 12:00:00 -, Notmuch Test Suite  wrote:
 > This is a test that messages are sent via SMTP
+> 
 EOF
 test_expect_equal_file OUTPUT EXPECTED

-- 
1.7.5.4



Distributed Notmuch

2012-01-08 Thread Ethan Glasser-Camp
Hi guys,

It's kind of academic for me right now because I'm mostly just using one 
computer, but one reason I've hesitated to switch over entirely to 
notmuch is that it's hard to distribute across many machines. The last 
time I wrote the list about this, David Bremner pointed me to gitmuch in 
the notmuch-scripts package, which uses git to synchronize tags. He 
wrote, "No one claims this is a great solution, but it works now."

In brainstorming about the One True Mail Setup, my friend suggested to 
me that Maildir/IMAP are not really the best choices for mail storage. 
Among other flaws: to synchronize mail via IMAP you have to check the 
headers of each message, which means a lot of bandwidth; you can't 
compress Maildir, meaning lots of wasted space; mechanisms to 
synchronize arbitrary tags have to be bolted on top. My friend suggested 
that instead it might be better to dump mail into some kind of database, 
for example CouchDB, and synchronize it that way. Of course, doing 
full-text indexing and tagging using an arbitrary DB would be a ton of 
work, so instead it probably makes the most sense to keep a Xapian 
instance on each node and feed all the mail to that. Tagging operations 
still have to be replicated, probably by an oplog that's also kept in 
Couch, so it's still a lot of work, but keeping things in Couch 
automatically gets you a lot of the replication mechanisms, offline 
access, etc., that would have to be bolted on/hacked up using tools like 
nmbug/gitmuch/rsync. I also see in the wiki that someone proposes to use 
git as the mail store, presumably for similar reasons. Xapian itself has 
the idea of master/slave replication but that doesn't really get you 
full offline access.

So my question for the wizards on this list is what their idea of the 
One True Mail Setup would be in a perfect, or slightly better, world, 
and what needs to be done to get there. I know some people use one 
notmuch install that they access remotely. For myself, I'm on a pretty 
limited Internet connection, so low bandwidth/offline access are big for 
me, and despite Nicolas Sebrecht and Sebastian Spaeth's heroic work on 
OfflineIMAP, it still uses a lot of bandwidth to sync. And obviously the 
whole point of this exercise is tag synchronization..

Ethan



[PATCH 1/2] clean up "compare thread ids" python test

2012-01-08 Thread Sebastian Spaeth
On Mon,  2 Jan 2012 14:51:26 +, Patrick Totzke  wrote:
> This makes the test script open the database in READ_ONLY mode
> and use the libraries own sorting methods instead of "sort".

+1 I don't want to fudge the tests (I don't know a thing about them), so
I can't judge the test outcome, but it is certainly good from the python side of
things. So I'll push this one.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120108/650448f0/attachment-0001.pgp>


[PATCH 1/4] Add the option "--reply-to" to notmuch reply.

2012-01-08 Thread Jani Nikula
On Fri,  6 Jan 2012 13:34:14 +, Mark Walters  
wrote:
> Possible values for this option are "sender" which replies just to
> sender and "all" (the default).
> 
> More precisely reply to sender follows these rules:
> reply only to sender unless it was the user
> reply only to all people on the "to" line unless they were all the user
> reply to all people on the "cc" line
> 
> Implementation details
> 
> We continue parsing addresses beyond the ones we reply to because
> we want to make sure the from address is correct. (At the very least it
> is the same as it would be if we replied to all.)
> 
> We overload the message variable in add_recipients_for_address_list so
> if it is NULL we parse the address (looking for the users address)
> but do not add to the message recipients list
> 
> We add the variable reply_to_all to the function chain to keep track
> of whether we should reply to everyone.
> ---
>  notmuch-reply.c |   48 +---
>  1 files changed, 37 insertions(+), 11 deletions(-)
> 
> diff --git a/notmuch-reply.c b/notmuch-reply.c
> index f8d5f64..9a77fe6 100644
> --- a/notmuch-reply.c
> +++ b/notmuch-reply.c
> @@ -212,7 +212,8 @@ add_recipients_for_address_list (GMimeMessage *message,
>   if (ret == NULL)
>   ret = addr;
>   } else {
> - g_mime_message_add_recipient (message, type, name, addr);
> +  if (message)
> +   g_mime_message_add_recipient (message, type, name, addr);
>   }
>   }
>  }
> @@ -292,7 +293,8 @@ reply_to_header_is_redundant (notmuch_message_t *message)
>  static const char *
>  add_recipients_from_message (GMimeMessage *reply,
>notmuch_config_t *config,
> -  notmuch_message_t *message)
> +  notmuch_message_t *message,
> +  int reply_to_all)
>  {
>  struct {
>   const char *header;
> @@ -332,9 +334,20 @@ add_recipients_from_message (GMimeMessage *reply,
>   recipients = notmuch_message_get_header (message,
>reply_to_map[i].fallback);
>  
> - addr = add_recipients_for_string (reply, config,
> -   reply_to_map[i].recipient_type,
> -   recipients);
> +
> + /* We add the addresses if we are replying to all or we have not yet 
> found
> +  * a non-user address. We have to keep parsing to make sure we do find 
> the
> +  * correct from address for the user, but we pass a NULL message
> +  */
> + if ((reply_to_all) || (g_mime_message_get_all_recipients (reply) == 
> NULL))

Looking into this, it occurred to me g_mime_message_get_all_recipients()
allocates a new InternetAddressList when the return value is
non-NULL. Thus this leaks memory. OTOH allocating and deallocating for
this purpose seems suboptimal. I'll think this over.

BR,
Jani.



> + addr = add_recipients_for_string (reply, config,
> +   reply_to_map[i].recipient_type,
> +   recipients);
> + else
> +  addr = add_recipients_for_string (NULL, config,
> +reply_to_map[i].recipient_type,
> +recipients);
> +
>   if (from_addr == NULL)
>   from_addr = addr;
>  }
> @@ -480,7 +493,8 @@ static int
>  notmuch_reply_format_default(void *ctx,
>notmuch_config_t *config,
>notmuch_query_t *query,
> -  notmuch_show_params_t *params)
> +  notmuch_show_params_t *params,
> +  int reply_to_all)
>  {
>  GMimeMessage *reply;
>  notmuch_messages_t *messages;
> @@ -509,7 +523,7 @@ notmuch_reply_format_default(void *ctx,
>   g_mime_message_set_subject (reply, subject);
>   }
>  
> - from_addr = add_recipients_from_message (reply, config, message);
> + from_addr = add_recipients_from_message (reply, config, message, 
> reply_to_all);
>  
>   if (from_addr == NULL)
>   from_addr = guess_from_received_header (config, message);
> @@ -558,7 +572,8 @@ static int
>  notmuch_reply_format_headers_only(void *ctx,
> notmuch_config_t *config,
> notmuch_query_t *query,
> -   unused (notmuch_show_params_t *params))
> +   unused (notmuch_show_params_t *params),
> +   int reply_to_all)
>  {
>  GMimeMessage *reply;
>  notmuch_messages_t *messages;
> @@ -598,7 +613,7 @@ notmuch_reply_format_headers_only(void *ctx,
>   g_mime_object_set_header (GMIME_OBJECT (reply),
>

[PATCH 2/2] python test "compare message ids"

2012-01-08 Thread Sebastian Spaeth
On Mon,  2 Jan 2012 14:51:27 +, Patrick Totzke  wrote:
> Introduces a second (trivial) test for the python
> bindings that searches for message ids and compares
> the output with that of `notmuch search`.

Test passes, so it went in.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120108/4b63d90c/attachment.pgp>


notmuch git's disk is full! ERROR pushing.

2012-01-08 Thread Sebastian Spaeth
Actually trying to push the above 2 patches, I get 

Writing objects: 100% (8/8), 1.25 KiB, done.
Total 8 (delta 5), reused 0 (delta 0)
error: unable to create temporary sha1 filename : No space left on device

fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
To ssh://spaetz at notmuchmail.org/git/notmuch
 ! [remote rejected] master -> master (n/a (unpacker error))
error: failed to push some refs to 'ssh://spaetz at notmuchmail.org/git/notmuch'

Sebastian
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120108/5efd3a93/attachment.pgp>


Info about notmuch database

2012-01-08 Thread Sebastian Spaeth
On Thu, 05 Jan 2012 16:04:22 +0100, Thomas Jost  
wrote:
> There's a description of the DB "schema" in lib/database.cc in the
> notmuch source code. But you may also consider just using libnotmuch
> instead, if that's enough for what you want to do.
> 
> Also: why Xapian? I'm already using something similar I wrote with
> Python, storing everything in a dictionary, using Pickle to save that to
> disk: 162 lines of code and 45 kb of data are enough to store my
> addressbook and have completion in Emacs...

Ohh, that sounds nice. Is that public somewhere?

Sebastian
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120108/0d4bfb23/attachment.pgp>


[PATCH 5/7] py3k: the basestring and unicode types are removed in python 3

2012-01-08 Thread Justus Winter
Hi Tomi, Hi Sebastian :)

Quoting Tomi Ollila (2012-01-04 19:07:11)
>On Mon, 02 Jan 2012 16:15:58 +0100, Sebastian Spaeth  
>wrote:
>> Happy new year. Pushed patches 1-4 of this series so far. Looking fine,

nice, thanks.

>> but ugh, the below seems like a rather ugly hack in a function that is
>> probably called quite often.
>>
>> Isn't there a more pretty variant avoiding these sys.version_info checks
>> all over the place?

Well, I rebased and updated this patch. There are now two different
implementations of _str like there are two Python3StringMixIn
classes. I'll send this patch as reply to this message.

>Does the Python3StringMixIn stuff in later patches already handle this
>patch -- and making this obsolete ?

No, that only handles the __str__ and __unicode__ stuff.

Cheers,
Justus


[PATCH] py3k: the basestring and unicode types are removed in python 3

2012-01-08 Thread Justus Winter
---
 bindings/python/notmuch/globals.py |   34 ++
 1 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/bindings/python/notmuch/globals.py 
b/bindings/python/notmuch/globals.py
index 32ed9ae..4138460 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -31,12 +31,34 @@ if sys.version_info[0] == 2:
 class Python3StringMixIn(object):
 def __str__(self):
 return unicode(self).encode('utf-8')
+
+
+def _str(value):
+"""Ensure a nicely utf-8 encoded string to pass to libnotmuch
+
+C++ code expects strings to be well formatted and
+unicode strings to have no null bytes."""
+if not isinstance(value, basestring):
+raise TypeError("Expected str or unicode, got %s" % type(value))
+if isinstance(value, unicode):
+return value.encode('UTF-8')
+return value
 else:
 class Python3StringMixIn(object):
 def __str__(self):
 return self.__unicode__()


+def _str(value):
+"""Ensure a nicely utf-8 encoded string to pass to libnotmuch
+
+C++ code expects strings to be well formatted and
+unicode strings to have no null bytes."""
+if not isinstance(value, str):
+raise TypeError("Expected str, got %s" % type(value))
+return value.encode('UTF-8')
+
+
 class Enum(object):
 """Provides ENUMS as "code=Enum(['a','b','c'])" where code.a=0 etc..."""
 def __init__(self, names):
@@ -202,18 +224,6 @@ class NotInitializedError(NotmuchError):
 status = STATUS.NOT_INITIALIZED


-def _str(value):
-"""Ensure a nicely utf-8 encoded string to pass to libnotmuch
-
-C++ code expects strings to be well formatted and
-unicode strings to have no null bytes."""
-if not isinstance(value, basestring):
-raise TypeError("Expected str or unicode, got %s" % str(type(value)))
-if isinstance(value, unicode):
-return value.encode('UTF-8')
-return value
-
-
 class NotmuchDatabaseS(Structure):
 pass
 NotmuchDatabaseP = POINTER(NotmuchDatabaseS)
-- 
1.7.7.3



Info about notmuch database

2012-01-08 Thread Thomas Jost
On Sun, 08 Jan 2012 13:59:30 +0100, Sebastian Spaeth  
wrote:
> On Thu, 05 Jan 2012 16:04:22 +0100, Thomas Jost  
> wrote:
> > There's a description of the DB "schema" in lib/database.cc in the
> > notmuch source code. But you may also consider just using libnotmuch
> > instead, if that's enough for what you want to do.
> > 
> > Also: why Xapian? I'm already using something similar I wrote with
> > Python, storing everything in a dictionary, using Pickle to save that to
> > disk: 162 lines of code and 45 kb of data are enough to store my
> > addressbook and have completion in Emacs...
> 
> Ohh, that sounds nice. Is that public somewhere?
> 
> Sebastian

https://github.com/Schnouki/dotfiles/blob/master/notmuch/addrbook.py

Maybe I should add more comments in it :)

Regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120108/4a45b952/attachment.pgp>


[PATCH 1/4] Add the option "--reply-to" to notmuch reply.

2012-01-08 Thread Mark Walters

On Sun, 08 Jan 2012 14:47:33 +0200, Jani Nikula  wrote:
> > +   /* We add the addresses if we are replying to all or we have not yet 
> > found
> > +* a non-user address. We have to keep parsing to make sure we do find 
> > the
> > +* correct from address for the user, but we pass a NULL message
> > +*/
> > +   if ((reply_to_all) || (g_mime_message_get_all_recipients (reply) == 
> > NULL))
> 
> Looking into this, it occurred to me g_mime_message_get_all_recipients()
> allocates a new InternetAddressList when the return value is
> non-NULL. Thus this leaks memory. OTOH allocating and deallocating for
> this purpose seems suboptimal. I'll think this over.

If we are happy with reply-to-sender stopping at the to: line
(so if you reply-to-sender to an email which you sent and has no-one
(apart from possibly you) on the to: line it would not give any
recipients) then we only have two cases and we could do something like

add_recipients_for_string for reply-to:/from:

if return value is non-null then we were the sender so then

add_recipients_for_string for to:

and then stop regardless (well we want to carry on parsing headers to
find the correct from: address to use but not adding any more
recipients).

It feels a bit hackish (it relies on the fact that if we found our
address in the Reply-to:/From: line we didn't find anyone else's
address). 

I think replying to an email which we sent and which does not have any
other person on the to: line is sufficiently rare that it doesn't really
matter what we do in this case.

Best wishes

Mark


[PATCH 1/4] Add the option "--reply-to" to notmuch reply.

2012-01-08 Thread Jani Nikula
On Sun, 08 Jan 2012 15:08:20 +, Mark Walters  
wrote:
> I think replying to an email which we sent and which does not have any
> other person on the to: line is sufficiently rare that it doesn't really
> matter what we do in this case.

I ended up fixing all of this properly. I'm hoping to send the patches
later today so you can have a look - the code will do a better job of
explaining itself than I'd do now. :)

BR,
Jani.


Python bindings for adoption

2012-01-08 Thread Justus Winter
Hi Sebastian, hi everyone :)

Quoting Sebastian Spaeth (2012-01-02 17:14:58)
>Hi all, a happy new year!
>
>After a few weeks of notmuch abstinence I am being overwhelmed with 750
>new notmuch mails, and I really don't have the time or will (nor does my
>family approve) to spend enormous amounts of time on notmuch. I am
>already neglecting offlineimap, which also needs some attention.
>
>As I have repeatedly stated that I want to hand over the maintainership
>of the notmuch python bindings, and I would like to do it asap. I feel
>that people like Patrick Totzke, or Justus Winter who generally have
>been working on this far more intensely than I recently did are both
>very well positioned to take on that role :-). Most importantly, they
>actually work with the bindings while I don't use them myself anymore.
>
>I will only merge bug fixes as of now, and not invest time to refactor
>the code or add lots of bells and whistles. Let me know if anyone would
>volunteer to take them on.

I've decided to step up as a new maintainer for the libnotmuch python
bindings. I assume that I'll have to mail an ssh public key to someone
for repository access, right?

Cheers,
Justus


nmbug changes

2012-01-08 Thread Justus Winter
Hey David,

Quoting David Bremner (2011-12-23 22:56:31)
>For those of you following/using the nmbug experiment, I made some
>slightly disruptive changes, in order to support auto-updating the web
>view on push.

I'm having trouble with nmbug, I did follow the instructions in this
mail and in the wiki, but nmbug never adds tags to my notmuch database
(it is supposed to do that, right?).

Consequently, nmbug status displays a long list of tags that aren't in
my notmuch database. Executing nmbug merge does not help, and stracing
nmbug revealed that it does only invoke notmuch with the search and
dump actions.

Any pointers?

Thanks,
Justus


[PATCH 4/4 v2] emacs: use pop-at-end functionality in archive/delete-message functions

2012-01-08 Thread Jameson Graef Rollins
This provides a smoother message processing flow by reducing the
number of key presses needed for these common operations.
---
Sorry, there were some errant extra parens at the end of these
function definitions.

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

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 4c2b507..a706637 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1454,7 +1454,7 @@ thread.
 "
 (interactive)
 (notmuch-show-remove-tag "inbox")
-(notmuch-show-next-open-message)))
+(notmuch-show-next-open-message t))

 (defun notmuch-show-archive-thread ()
   "Archive each message in thread, then show next thread from search.
@@ -1485,7 +1485,7 @@ thread.
 "
 (interactive)
 (notmuch-show-add-tag "deleted")
-(notmuch-show-next-open-message)))
+(notmuch-show-next-open-message t))

 (defun notmuch-show-delete-thread ()
   "Delete each message in thread, then show next thread from search.
-- 
1.7.7.3



[PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message

2012-01-08 Thread Jameson Graef Rollins
This adds two new function, notmuch-show-{archive,delete}-message,
that archive/delete the current message, and then move to the next
open one.
---
Sorry, there were some errant extra parens at the end of these
function definitions.

 emacs/notmuch-show.el |   24 
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index e1d15f4..b2e7829 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1436,6 +1436,18 @@ argument, hide all of the messages."
(if show-next
(notmuch-search-show-thread)))

+(defun notmuch-show-archive-message ()
+  "Archive the current message and advance.
+
+After the last message is reached, either the buffer will be
+closed and the cursor will move to the search result if
+available, or the cursor will move to the end of the current
+thread.
+"
+(interactive)
+(notmuch-show-remove-tag "inbox")
+(notmuch-show-next-open-message))
+
 (defun notmuch-show-archive-thread ()
   "Archive each message in thread, then show next thread from search.

@@ -1455,6 +1467,18 @@ buffer."
   (interactive)
   (notmuch-show-tag-thread-internal "-" "inbox" nil))

+(defun notmuch-show-delete-message ()
+  "Delete the current message and advance.
+
+After the last message is reached, either the buffer will be
+closed and the cursor will move to the search result if
+available, or the cursor will move to the end of the current
+thread.
+"
+(interactive)
+(notmuch-show-add-tag "deleted")
+(notmuch-show-next-open-message))
+
 (defun notmuch-show-delete-thread ()
   "Delete each message in thread, then show next thread from search.

-- 
1.7.7.3



[PATCH 4/4 v3] emacs: use pop-at-end functionality in archive/delete-message functions

2012-01-08 Thread Jameson Graef Rollins
This provides a smoother message processing flow by reducing the
number of key presses needed for these common operations.
---
Sorry sorry.  I originally missed the problem in patch 1/4, so I had
to modify this patch again to apply against the new version of the
previous.  So sorry for the noise, and thanks to amdragon for pointing
all of this out.

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

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b9ec584..a706637 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1454,7 +1454,7 @@ thread.
 "
 (interactive)
 (notmuch-show-remove-tag "inbox")
-(notmuch-show-next-open-message))
+(notmuch-show-next-open-message t))

 (defun notmuch-show-archive-thread ()
   "Archive each message in thread, then show next thread from search.
@@ -1485,7 +1485,7 @@ thread.
 "
 (interactive)
 (notmuch-show-add-tag "deleted")
-(notmuch-show-next-open-message))
+(notmuch-show-next-open-message t))

 (defun notmuch-show-delete-thread ()
   "Delete each message in thread, then show next thread from search.
-- 
1.7.7.3



[PATCH] man: add missing SEE ALSO header to notmuch reply man page

2012-01-08 Thread Jani Nikula
Signed-off-by: Jani Nikula 
---
 man/man1/notmuch-reply.1 |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 099d808..db464d8 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -58,6 +58,9 @@ thread, replying to the entire thread allows for the reply to 
comment
 on issue found in multiple patches.
 .RE
 .RE
+
+.SH SEE ALSO
+
 \fBnotmuch\fR(1), \fBnotmuch-config\fR(1), \fBnotmuch-count\fR(1),
 \fBnotmuch-dump\fR(5), \fBnotmuch-hooks\fR(5), \fBnotmuch-new\fR(1),
 \fBnotmuch-part\fR(1), \fBnotmuch-restore\fR(1),
-- 
1.7.5.4



[PATCH v2 0/6] reply to sender

2012-01-08 Thread Jani Nikula
Hi all, here's v2 of the reply-to-sender series.

Patches 1 & 2 are exactly the same as before.

Changes since first version:

- Patch 3: Settle on --reply-to=(all|sender) option for "notmuch
  reply". This was originally Carl Worth's suggestion, predates this
  patch set, and, as you'd expect, is in line with the rest of the
  CLI. Acked by David on IRC.

- Patch 3: Handle replying to user's own messages gracefully. Credits
  to Mark Walters for his earlier work on this.

- Patch 3: Update man page.

- Patch 4: Change emacs implementation to keep old function names for
  old reply-to-all functionality, and add new reply-to-sender versions
  for new functionality, instead of vice versa. Suggested by Mark
  Walters.

- Add patch 5 to change emacs keybindings, 'r' for reply-to-sender,
  'R' for reply-to-all. I think everyone was in favour of this.

- Add patch 6, written by Mark Winters, to test the cli.

Comments are, as always, welcome.


BR,
Jani.

Jani Nikula (5):
  cli: fix use of uninitialized variable in "notmuch reply"
  cli: convert "notmuch reply" to use the new argument parser
  cli: add support for replying just to the sender in "notmuch reply"
  emacs: add support for replying just to the sender
  emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

Mark Walters (1):
  test: add tests for "notmuch reply" --reply-to=sender

 emacs/notmuch-mua.el |9 ++-
 emacs/notmuch-show.el|   12 ++-
 emacs/notmuch.el |   11 ++-
 man/man1/notmuch-reply.1 |   28 +-
 notmuch-reply.c  |  155 ++
 test/notmuch-test|1 +
 test/reply-to-sender |  209 ++
 7 files changed, 356 insertions(+), 69 deletions(-)
 create mode 100755 test/reply-to-sender

-- 
1.7.5.4



[PATCH v2 1/6] cli: fix use of uninitialized variable in "notmuch reply"

2012-01-08 Thread Jani Nikula
notmuch_show_params_t params is only initialized partially in
notmuch_reply_command(). The only field that is used uninitialized is
params.decrypt. It is usually non-zero, making "notmuch reply" on encrypted
messages work by coincidence.

Initialize params properly, and set params.decrypt as needed.

Signed-off-by: Jani Nikula 
---
 notmuch-reply.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index f8d5f64..1f33a86 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -621,11 +621,9 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 char *opt, *query_string;
 int i, ret = 0;
 int (*reply_format_func)(void *ctx, notmuch_config_t *config, 
notmuch_query_t *query, notmuch_show_params_t *params);
-notmuch_show_params_t params;
+notmuch_show_params_t params = { .part = -1 };

 reply_format_func = notmuch_reply_format_default;
-params.part = -1;
-params.cryptoctx = NULL;

 argc--; argv++; /* skip subcommand argument */

@@ -647,10 +645,12 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
} else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
if (params.cryptoctx == NULL) {
GMimeSession* session = g_object_new(g_mime_session_get_type(), 
NULL);
-   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
"gpg")))
+   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
"gpg"))) {
fprintf (stderr, "Failed to construct gpg context.\n");
-   else
+   } else {
+   params.decrypt = TRUE;

g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
+   }
g_object_unref (session);
session = NULL;
}
-- 
1.7.5.4



[PATCH v2 2/6] cli: convert "notmuch reply" to use the new argument parser

2012-01-08 Thread Jani Nikula
Use the new notmuch argument parser to handle arguments in "notmuch
reply". There should be no functional changes.

Signed-off-by: Jani Nikula 
---
 notmuch-reply.c |   75 +++
 1 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 1f33a86..000f6da 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -612,62 +612,61 @@ notmuch_reply_format_headers_only(void *ctx,
 return 0;
 }

+enum {
+FORMAT_DEFAULT,
+FORMAT_HEADERS_ONLY,
+};
+
 int
 notmuch_reply_command (void *ctx, int argc, char *argv[])
 {
 notmuch_config_t *config;
 notmuch_database_t *notmuch;
 notmuch_query_t *query;
-char *opt, *query_string;
-int i, ret = 0;
+char *query_string;
+int opt_index, ret = 0;
 int (*reply_format_func)(void *ctx, notmuch_config_t *config, 
notmuch_query_t *query, notmuch_show_params_t *params);
 notmuch_show_params_t params = { .part = -1 };
+int format = FORMAT_DEFAULT;
+notmuch_bool_t decrypt = FALSE;
+
+notmuch_opt_desc_t options[] = {
+   { NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
+ (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
+ { "headers-only", FORMAT_HEADERS_ONLY },
+ { 0, 0 } } },
+   { NOTMUCH_OPT_BOOLEAN, &decrypt, "decrypt", 'd', 0 },
+   { 0, 0, 0, 0, 0 }
+};

-reply_format_func = notmuch_reply_format_default;
-
-argc--; argv++; /* skip subcommand argument */
+opt_index = parse_arguments (argc, argv, options, 1);
+if (opt_index < 0) {
+   /* diagnostics already printed */
+   return 1;
+}

-for (i = 0; i < argc && argv[i][0] == '-'; i++) {
-   if (strcmp (argv[i], "--") == 0) {
-   i++;
-   break;
-   }
-if (STRNCMP_LITERAL (argv[i], "--format=") == 0) {
-   opt = argv[i] + sizeof ("--format=") - 1;
-   if (strcmp (opt, "default") == 0) {
-   reply_format_func = notmuch_reply_format_default;
-   } else if (strcmp (opt, "headers-only") == 0) {
-   reply_format_func = notmuch_reply_format_headers_only;
-   } else {
-   fprintf (stderr, "Invalid value for --format: %s\n", opt);
-   return 1;
-   }
-   } else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
-   if (params.cryptoctx == NULL) {
-   GMimeSession* session = g_object_new(g_mime_session_get_type(), 
NULL);
-   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
"gpg"))) {
-   fprintf (stderr, "Failed to construct gpg context.\n");
-   } else {
-   params.decrypt = TRUE;
-   
g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);
-   }
-   g_object_unref (session);
-   session = NULL;
-   }
+if (format == FORMAT_HEADERS_ONLY)
+   reply_format_func = notmuch_reply_format_headers_only;
+else
+   reply_format_func = notmuch_reply_format_default;
+
+if (decrypt) {
+   GMimeSession* session = g_object_new (g_mime_session_get_type(), NULL);
+   params.cryptoctx = g_mime_gpg_context_new (session, "gpg");
+   if (params.cryptoctx) {
+   g_mime_gpg_context_set_always_trust ((GMimeGpgContext*) 
params.cryptoctx, FALSE);
+   params.decrypt = TRUE;
} else {
-   fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
-   return 1;
+   fprintf (stderr, "Failed to construct gpg context.\n");
}
+   g_object_unref (session);
 }

-argc -= i;
-argv += i;
-
 config = notmuch_config_open (ctx, NULL, NULL);
 if (config == NULL)
return 1;

-query_string = query_string_from_args (ctx, argc, argv);
+query_string = query_string_from_args (ctx, argc-opt_index, 
argv+opt_index);
 if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return 1;
-- 
1.7.5.4



[PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"

2012-01-08 Thread Jani Nikula
Add new option --reply-to=(all|sender) to "notmuch reply" to select whether
to reply to all (sender and all recipients), or just sender. Reply to all
remains the default.

Credits to Mark Walters  for his similar earlier
work where I picked up the basic idea of handling reply-to-sender in
add_recipients_from_message(). All bugs are mine, though.

Signed-off-by: Jani Nikula 

---

Settled on --reply-to=(all|sender) per Carl's earlier suggestion
(id:87pqn5cg4g.fsf at yoom.home.cworth.org) and David's approval on IRC.
---
 man/man1/notmuch-reply.1 |   28 +---
 notmuch-reply.c  |   78 --
 2 files changed, 84 insertions(+), 22 deletions(-)

diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1
index 099d808..21afa35 100644
--- a/man/man1/notmuch-reply.1
+++ b/man/man1/notmuch-reply.1
@@ -14,11 +14,13 @@ Constructs a reply template for a set of messages.
 To make replying to email easier,
 .B notmuch reply
 takes an existing set of messages and constructs a suitable mail
-template. The Reply-to header (if any, otherwise From:) is used for
-the To: address. Vales from the To: and Cc: headers are copied, but
-not including any of the current user's email addresses (as configured
-in primary_mail or other_email in the .notmuch\-config file) in the
-recipient list
+template. The Reply-to: header (if any, otherwise From:) is used for
+the To: address. Unless
+.BR \-\-reply-to=sender
+is specified, values from the To: and Cc: headers are copied, but not
+including any of the current user's email addresses (as configured in
+primary_mail or other_email in the .notmuch\-config file) in the
+recipient list.

 It also builds a suitable new subject, including Re: at the front (if
 not already present), and adding the message IDs of the messages being
@@ -45,6 +47,22 @@ Includes subject and quoted message body.
 Only produces In\-Reply\-To, References, To, Cc, and Bcc headers.
 .RE
 .RE
+.RS
+.TP 4
+.BR \-\-reply\-to= ( all | sender )
+.RS
+.TP 4
+.BR all " (default)"
+Replies to all addresses.
+.TP 4
+.BR sender
+Replies only to the sender. If Reply-to: header (if any, otherwise
+From:) is any of the current user's configured email addresses
+(replying to user's own message), try To:, Cc:, and Bcc: headers in
+this order, and use the addresses in the first that contains something
+other than only the user's addresses for the To: address.
+.RE
+.RE

 See \fBnotmuch-search-terms\fR(7)
 for details of the supported syntax for .
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 000f6da..71946b3 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -170,7 +170,7 @@ address_is_users (const char *address, notmuch_config_t 
*config)

 /* For each address in 'list' that is not configured as one of the
  * user's addresses in 'config', add that address to 'message' as an
- * address of 'type'.
+ * address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -179,7 +179,8 @@ static const char *
 add_recipients_for_address_list (GMimeMessage *message,
 notmuch_config_t *config,
 GMimeRecipientType type,
-InternetAddressList *list)
+InternetAddressList *list,
+notmuch_bool_t add)
 {
 InternetAddress *address;
 int i;
@@ -197,7 +198,7 @@ add_recipients_for_address_list (GMimeMessage *message,
continue;

add_recipients_for_address_list (message, config,
-type, group_list);
+type, group_list, add);
} else {
InternetAddressMailbox *mailbox;
const char *name;
@@ -211,7 +212,7 @@ add_recipients_for_address_list (GMimeMessage *message,
if (address_is_users (addr, config)) {
if (ret == NULL)
ret = addr;
-   } else {
+   } else if (add) {
g_mime_message_add_recipient (message, type, name, addr);
}
}
@@ -222,7 +223,7 @@ add_recipients_for_address_list (GMimeMessage *message,

 /* For each address in 'recipients' that is not configured as one of
  * the user's addresses in 'config', add that address to 'message' as
- * an address of 'type'.
+ * an address of 'type', if 'add' is true.
  *
  * The first address encountered that *is* the user's address will be
  * returned, (otherwise NULL is returned).
@@ -231,7 +232,8 @@ static const char *
 add_recipients_for_string (GMimeMessage *message,
   notmuch_config_t *config,
   GMimeRecipientType type,
-  const char *recipients)
+  const char *recipients,
+  notmuch_bool_t add)
 {
 InternetAddressList

[PATCH v2 4/6] emacs: add support for replying just to the sender

2012-01-08 Thread Jani Nikula
Provide reply to sender counterparts to the search and show reply
functions. Add key binding 'R' to reply to sender, while keeping 'r' as
reply to all, both in search and show views.

Signed-off-by: Jani Nikula 
---
 emacs/notmuch-mua.el  |9 ++---
 emacs/notmuch-show.el |   10 --
 emacs/notmuch.el  |9 -
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7114e48..5b15255 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -71,12 +71,15 @@ list."
(push header message-hidden-headers)))
notmuch-mua-hidden-headers))

-(defun notmuch-mua-reply (query-string &optional sender)
+(defun notmuch-mua-reply (query-string &optional sender reply-all)
   (let (headers
body
(args '("reply")))
 (if notmuch-show-process-crypto
(setq args (append args '("--decrypt"
+(if reply-all
+   (setq args (append args '("--reply-to=all")))
+  (setq args (append args '("--reply-to=sender"
 (setq args (append args (list query-string)))
 ;; This make assumptions about the output of `notmuch reply', but
 ;; really only that the headers come first followed by a blank
@@ -217,13 +220,13 @@ the From: address first."
(notmuch-mua-forward-message))
 (notmuch-mua-forward-message)))

-(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender)
+(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender 
reply-all)
   "Invoke the notmuch reply window."
   (interactive "P")
   (let ((sender
 (when prompt-for-sender
   (notmuch-mua-prompt-for-sender
-(notmuch-mua-reply query-string sender)))
+(notmuch-mua-reply query-string sender reply-all)))

 (defun notmuch-mua-send-and-exit (&optional arg)
   (interactive "P")
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..96eea19 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -933,6 +933,7 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
(define-key map "m" 'notmuch-mua-new-mail)
(define-key map "f" 'notmuch-show-forward-message)
(define-key map "r" 'notmuch-show-reply)
+   (define-key map "R" 'notmuch-show-reply-sender)
(define-key map "|" 'notmuch-show-pipe-message)
(define-key map "w" 'notmuch-show-save-attachments)
(define-key map "V" 'notmuch-show-view-raw-message)
@@ -1237,9 +1238,14 @@ any effects from previous calls to
   (notmuch-show-previous-message)

 (defun notmuch-show-reply (&optional prompt-for-sender)
-  "Reply to the current message."
+  "Reply to the sender and all recipients of the current message."
   (interactive "P")
-  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender))
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t))
+
+(defun notmuch-show-reply-sender (&optional prompt-for-sender)
+  "Reply to the sender of the current message."
+  (interactive "P")
+  (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil))

 (defun notmuch-show-forward-message (&optional prompt-for-sender)
   "Forward the current message."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index fde2377..5974d6b 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -207,6 +207,7 @@ For a mouse binding, return nil."
 (define-key map "p" 'notmuch-search-previous-thread)
 (define-key map "n" 'notmuch-search-next-thread)
 (define-key map "r" 'notmuch-search-reply-to-thread)
+(define-key map "R" 'notmuch-search-reply-to-thread-sender)
 (define-key map "m" 'notmuch-mua-new-mail)
 (define-key map "s" 'notmuch-search)
 (define-key map "o" 'notmuch-search-toggle-order)
@@ -441,10 +442,16 @@ Complete list of currently available key bindings:
   (error "End of search results"

 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
+  "Begin composing a reply-all to the entire current thread in a new buffer."
+  (interactive "P")
+  (let ((message-id (notmuch-search-find-thread-id)))
+(notmuch-mua-new-reply message-id prompt-for-sender t)))
+
+(defun notmuch-search-reply-to-thread-sender (&optional prompt-for-sender)
   "Begin composing a reply to the entire current thread in a new buffer."
   (interactive "P")
   (let ((message-id (notmuch-search-find-thread-id)))
-(notmuch-mua-new-reply message-id prompt-for-sender)))
+(notmuch-mua-new-reply message-id prompt-for-sender nil)))

 (defun notmuch-call-notmuch-process (&rest args)
   "Synchronously invoke \"notmuch\" with the given list of arguments.
-- 
1.7.5.4



[PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jani Nikula
Change the default reply key bindings, making 'r' reply-to-sender and 'R'
reply-to-all.

Signed-off-by: Jani Nikula 

---

It seemed to me that most people wanted this, and nobody spoke for keeping
the old binding now that we have reply-to-sender. This as a separate patch
so it's easy to drop if needed.
---
 emacs/notmuch-show.el |4 ++--
 emacs/notmuch.el  |4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 96eea19..8f8ea93 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -932,8 +932,8 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
(define-key map "s" 'notmuch-search)
(define-key map "m" 'notmuch-mua-new-mail)
(define-key map "f" 'notmuch-show-forward-message)
-   (define-key map "r" 'notmuch-show-reply)
-   (define-key map "R" 'notmuch-show-reply-sender)
+   (define-key map "r" 'notmuch-show-reply-sender)
+   (define-key map "R" 'notmuch-show-reply)
(define-key map "|" 'notmuch-show-pipe-message)
(define-key map "w" 'notmuch-show-save-attachments)
(define-key map "V" 'notmuch-show-view-raw-message)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 5974d6b..e158138 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -206,8 +206,8 @@ For a mouse binding, return nil."
 (define-key map ">" 'notmuch-search-last-thread)
 (define-key map "p" 'notmuch-search-previous-thread)
 (define-key map "n" 'notmuch-search-next-thread)
-(define-key map "r" 'notmuch-search-reply-to-thread)
-(define-key map "R" 'notmuch-search-reply-to-thread-sender)
+(define-key map "r" 'notmuch-search-reply-to-thread-sender)
+(define-key map "R" 'notmuch-search-reply-to-thread)
 (define-key map "m" 'notmuch-mua-new-mail)
 (define-key map "s" 'notmuch-search)
 (define-key map "o" 'notmuch-search-toggle-order)
-- 
1.7.5.4



[PATCH v2 6/6] test: add tests for "notmuch reply" --reply-to=sender

2012-01-08 Thread Jani Nikula
From: Mark Walters 

---

This is Mark's work; just a one line change by Jani to take into account a
minor change in replying to one's own message.
---
 test/notmuch-test|1 +
 test/reply-to-sender |  209 ++
 2 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100755 test/reply-to-sender

diff --git a/test/notmuch-test b/test/notmuch-test
index e40ef86..6a99ae3 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -33,6 +33,7 @@ TESTS="
   thread-naming
   raw
   reply
+  reply-to-sender
   dump-restore
   uuencode
   thread-order
diff --git a/test/reply-to-sender b/test/reply-to-sender
new file mode 100755
index 000..caceeb2
--- /dev/null
+++ b/test/reply-to-sender
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+test_description="\"notmuch reply --reply-to=sender\" in several variations"
+. ./test-lib.sh
+
+test_begin_subtest "Basic reply-to-sender"
+add_message '[from]="Sender "' \
+ [to]=test_suite at notmuchmail.org \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="basic reply-to-sender test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 
+Subject: Re: notmuch-reply-test
+To: Sender 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Sender  wrote:
+> basic reply-to-sender test"
+
+test_begin_subtest "From Us, Basic reply to message"
+add_message '[from]="Notmuch Test Suite "' \
+'[to]="Recipient "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="basic reply-to-from-us test"'
+
+output=$(notmuch reply --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 
+Subject: Re: notmuch-reply-test
+To: Recipient 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Notmuch Test Suite  wrote:
+> basic reply-to-from-us test"
+
+test_begin_subtest "Multiple recipients"
+add_message '[from]="Sender "' \
+'[to]="test_suite at notmuchmail.org, Someone Else "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="Multiple recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 
+Subject: Re: notmuch-reply-test
+To: Sender 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Sender  wrote:
+> Multiple recipients"
+
+test_begin_subtest "From Us, Multiple TO recipients"
+add_message '[from]="Notmuch Test Suite "' \
+'[to]="Recipient , Someone Else "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="From Us, Multiple TO recipients"'
+
+output=$(notmuch reply  --reply-to=sender  id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 
+Subject: Re: notmuch-reply-test
+To: Recipient , Someone Else 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Notmuch Test Suite  wrote:
+> From Us, Multiple TO recipients"
+
+test_begin_subtest "Reply with CC"
+add_message '[from]="Sender "' \
+ [to]=test_suite at notmuchmail.org \
+'[cc]="Other Parties "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 
+Subject: Re: notmuch-reply-test
+To: Sender 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Sender  wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply with CC"
+add_message '[from]="Notmuch Test Suite "' \
+'[to]="Recipient "' \
+'[cc]="Other Parties "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 
+Subject: Re: notmuch-reply-test
+To: Recipient 
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -, Notmuch Test Suite  wrote:
+> reply with CC"
+
+test_begin_subtest "From Us, Reply no TO but with CC"
+add_message '[from]="Notmuch Test Suite "' \
+'[cc]="Other Parties "' \
+ [subject]=notmuch-reply-test \
+'[date]="Tue, 05 Jan 2010 15:43:56 -"' \
+'[body]="reply with CC"'
+
+output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})
+test_expect_equal "$output" "From: Notmuch Test Suite 
+Subject: Re: notmuch-reply-test

[PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jeremy Nickurak
On Sun, Jan 8, 2012 at 14:48, Jani Nikula  wrote:
> It seemed to me that most people wanted this, and nobody spoke for keeping
> the old binding now that we have reply-to-sender. This as a separate patch
> so it's easy to drop if needed.

FWIW, I generally prefer reply-all as the default. In my experience,
when a message is sent to a bunch of people, it's usually treated as a
"forum" discussion where everybody wants to be in on everything. Also,
once you've started composing, it's much easier to delete people you
don't want included than to add people who are no longer referenced in
the new buffer at all.


nmbug changes

2012-01-08 Thread David Bremner
On Sun, 08 Jan 2012 16:24:06 -, Justus Winter <4winter at 
informatik.uni-hamburg.de> wrote:

> I'm having trouble with nmbug, I did follow the instructions in this
> mail and in the wiki, but nmbug never adds tags to my notmuch database
> (it is supposed to do that, right?).

In case you just want to load the tags in the git repo into your notmuch
database, try running "nmbug checkout".

It might be the instructions on "getting started" could be updated here?
Perhaps someone who has gotten started more recently can chime in here.

David



Python bindings for adoption

2012-01-08 Thread David Bremner
On Sun, 08 Jan 2012 16:16:06 -, Justus Winter <4winter at 
informatik.uni-hamburg.de> wrote:
> 
> I've decided to step up as a new maintainer for the libnotmuch python
> bindings. I assume that I'll have to mail an ssh public key to someone
> for repository access, right?
> 

That's right. Carl (in copy) handles repository access.

d





[PATCH v2 3/6] cli: add support for replying just to the sender in "notmuch reply"

2012-01-08 Thread Mark Walters

I like this version (of the whole series) but have two queries. (Note I
haven't actually tried it out yet: I have just been reading the code.)

> + /* Force recipient type in reply-to-sender mode just in case replying to
> +  * user's own message finds recipients in Cc/Bcc fields only.
> +  */
> + if (reply_all)
> + recipient_type = reply_to_map[i].recipient_type;
> + else
> + recipient_type = GMIME_RECIPIENT_TYPE_TO;
> +
> + addr = add_recipients_for_string (reply, config, recipient_type,
> +   recipients, add_recipients);
> +

Why force the recipient type?  I do not think notmuch should ever move
bcc people onto a different header. I think that will bite someone when
it leaks information.

I would be happy with either empty headers or with the people staying
as bcc.

In the cc: case I have no preference (as those addresses are already
public) but I would suggest being consistent with bcc so either empty
headers or keep them in the cc line.

> for (messages = notmuch_query_search_messages (query);
> notmuch_messages_valid (messages);
> notmuch_messages_move_to_next (messages))
> {
[...]
>   (void)add_recipients_from_message (reply, config, message, reply_all);

Since the above logic is applied to each email individually I think
working out the recipients when replying to multiple emails (e.g.,
reply-to-sender on a thread) could be very confusing. Some of the people
being replied to will have been senders, some recipients (it is very
likely that the thread contains messages we sent), some could even be
cc, bcc people. Personally, I would have no idea what to expect from
reply-to-sender in this case.

(My personal choice would be not to allow notmuch-reply-to-sender if
multiple messages are specified. But I can obtain that by unbinding "r"
in the notmuch-search-mode-map keymap.)

Best wishes

Mark



[PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jameson Graef Rollins
On Sun, 8 Jan 2012 15:01:30 -0700, Jeremy Nickurak  wrote:
> FWIW, I generally prefer reply-all as the default. In my experience,
> when a message is sent to a bunch of people, it's usually treated as a
> "forum" discussion where everybody wants to be in on everything. Also,
> once you've started composing, it's much easier to delete people you
> don't want included than to add people who are no longer referenced in
> the new buffer at all.

That's a good point.  I think that maybe people are wanting to protect
against the accidental reply to all when you only mean to reply to the
sender.

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


[PATCH v2 5/6] emacs: bind 'r' to reply-to-sender and 'R' to reply-to-all

2012-01-08 Thread Jeremy Nickurak
On Sun, Jan 8, 2012 at 16:32, Jameson Graef Rollins
 wrote:
> That's a good point. ?I think that maybe people are wanting to protect
> against the accidental reply to all when you only mean to reply to the
> sender.

Certainly a worthy cause. All I'm saying is I make the mistake in the
other direction more frequently ;)


[PATCH] emacs: call "notmuch tag" only once when archiving a thread

2012-01-08 Thread Aaron Ecay
On Thu, 05 Jan 2012 22:32:16 +0200, Jani Nikula  wrote:

[...]

> In the show view it only modifies the messages that are currently
> visible. This is to make sure you don't accidentally archive things that
> have arrived after refreshing the buffer. I think this is safest.

Hmm.  Perhaps it would make sense to add a check in the search view that
the thread being archived[1] has the same number of messages as it did
when the buffer was constructed.  (The information on how many messages
the thread has is in the buffer; we would then compare this to the result
of ?notmuch count thread:000foo? when the user requests to archive.)  If
the counts don?t match, the interface should show a message in the echo
area and (probably) refuse to do the tagging.

We could also optionally use this strategy in the search view too.  The
error message is simple there: ?New messages have arrived; refresh
thread view before archiving.?  (It doesn?t make as much sense to tell
people to refresh a search view ? it could be an expensive operation
and/or may not be idempotent if some thread?s tags have been changed.
So it?s harder to say what the advice should be in that case.)

If other people think it would be useful, I can work on a patch to
implement this approach.

Footnotes:
[1] Or having its tags changed generally.

-- 
Aaron Ecay


[PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging

2012-01-08 Thread Aaron Ecay
Jameson,

Some comments below:

On Sat,  7 Jan 2012 14:28:12 -0800, Jameson Graef Rollins  wrote:
> Instead of having a function that is only used for archiving a thread,
> we instead make it useful for any tagging operation.  The new
> function, notmuch-show-tag-thread-internal, now takes two more
> arguments, for the "sign" of the tagging operation ("-" or "+"), and
> the tag to be added or removed.  This will allow this function to be
> used for any generic thread tagging operation.
> 
> The higher level functions that call this function are modified
> accordingly.
> ---
>  emacs/notmuch-show.el |   34 --
>  1 files changed, 20 insertions(+), 14 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 5502efd..1e16f05 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -1414,20 +1414,26 @@ argument, hide all of the messages."
>(interactive)
>(backward-button 1))
>  
> -(defun notmuch-show-archive-thread-internal (show-next)
> +(defun notmuch-show-tag-thread-internal (sign tag show-next)

A couple of comments on the arguments:
- It would be good to make show-next &optional.  This will enable code
  to call the fn with only two arguments, and not showing next will be
  the default behavior.
- A more lispy way of specifying the sign would be to use a
  boolean.  Perhaps you could call this ?remove?; a value of ?t? would
  remove the tag; ?nil? would add it.  Moving this argument after ?tag?
  and also making it &optional woudl allow this fn to be called with one
  arg to add a tag.  (Maybe this is too minimalist and API, however.) 

>;; Remove the tag from the current set of messages.
>(goto-char (point-min))
> -  (loop do (notmuch-show-remove-tag "inbox")
> - until (not (notmuch-show-goto-message-next)))
> -  ;; Move to the next item in the search results, if any.
> -  (let ((parent-buffer notmuch-show-parent-buffer))
> -(notmuch-kill-this-buffer)
> -(if parent-buffer
> - (progn
> -   (switch-to-buffer parent-buffer)
> -   (forward-line)
> -   (if show-next
> -   (notmuch-search-show-thread))
> +  (let ((tag-function))

No second set of parens is needed around tag-function.

> +(cond
> + ((string= sign "-")
> +  (setq tag-function 'notmuch-show-remove-tag))
> + ((string= sign "+")
> +  (setq tag-function 'notmuch-show-add-tag)))
> +(loop do (funcall tag-function tag)
> +   until (not (notmuch-show-goto-message-next)))
> +;; Move to the next item in the search results, if any.

Does it make sense to separate the tagging and the movement?  It seems
plausible that some code somewhere might want to add/remove a tag from
all messages in the thread w/o changing the display.

> +(let ((parent-buffer notmuch-show-parent-buffer))
> +  (notmuch-kill-this-buffer)
> +  (if parent-buffer
> +   (progn
> + (switch-to-buffer parent-buffer)
> + (forward-line)
> + (if show-next
> + (notmuch-search-show-thread)))

-- 
Aaron Ecay


[PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end

2012-01-08 Thread Aaron Ecay
Jameson,

One small, stylistic/nitpicky comment :)

On Sat,  7 Jan 2012 17:26:53 -0800, Jameson Graef Rollins  wrote:
> This will allow for keybindings that achieve a smoother message
> processing flow by reducing the number of key presses needed for most
> common operations.
> ---
>  emacs/notmuch-show.el |   12 +---
>  1 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 8bb052e..e7bb958 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -1264,17 +1264,23 @@ any effects from previous calls to
>(notmuch-show-mark-read)
>(notmuch-show-message-adjust))
>  
> -(defun notmuch-show-next-open-message ()
> +(defun notmuch-show-next-open-message (&optional pop-at-end)
>"Show the next message."
>(interactive)
> -  (let (r)
> +  (let ((r)
> + (parent-buffer notmuch-show-parent-buffer))

No second set of parentheses is needed around r.  Also, it is more
idiomatic to put the initialized variable (i.e. parent-buffer) before
the uninitialized one (r).

>  (while (and (setq r (notmuch-show-goto-message-next))
>   (not (notmuch-show-message-visible-p
>  (if r
>   (progn
> (notmuch-show-mark-read)
> (notmuch-show-message-adjust))
> -  (goto-char (point-max)
> +  (if (and parent-buffer pop-at-end)
> +   (progn
> + (kill-this-buffer)
> + (switch-to-buffer parent-buffer)
> + (forward-line 1))
> + (goto-char (point-max))
>  
>  (defun notmuch-show-previous-open-message ()
>"Show the previous message."
> -- 
> 1.7.7.3
> 
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

-- 
Aaron Ecay


[PATCH] emacs: call "notmuch tag" only once when archiving a thread

2012-01-08 Thread Austin Clements
Quoth Aaron Ecay on Jan 08 at  7:56 pm:
> On Thu, 05 Jan 2012 22:32:16 +0200, Jani Nikula  wrote:
> 
> [...]
> 
> > In the show view it only modifies the messages that are currently
> > visible. This is to make sure you don't accidentally archive things that
> > have arrived after refreshing the buffer. I think this is safest.
> 
> Hmm.  Perhaps it would make sense to add a check in the search view that
> the thread being archived[1] has the same number of messages as it did
> when the buffer was constructed.  (The information on how many messages
> the thread has is in the buffer; we would then compare this to the result
> of ?notmuch count thread:000foo? when the user requests to archive.)  If
> the counts don?t match, the interface should show a message in the echo
> area and (probably) refuse to do the tagging.

That sounds like a clever workaround.

There's been quite a bit of discussion on fixing this properly.  See,
for example
id:"CAH-f9WsPj=1Eu=g3sOePJgCTBFs6HrLdLq18xMEnJ8aZ00yCEg at mail.gmail.com".
The gist is that we need to include message IDs (or document IDs) in
the search output and use these in tagging operations, rather than the
unstable thread:XXX queries.  Unfortunately, actually fixing this got
stalled since adding this information the text format is a fool's
errand (having been the fool, I can say this!), so we need to switch
Emacs over to using the JSON search format first.  However, once
that's done, it's a relatively simple change.


[PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Aaron Ecay
Jameson,

One comment

On Sat,  7 Jan 2012 14:28:11 -0800, Jameson Graef Rollins  wrote:
> The new customization variable, notmuch-search-exclude-deleted, when
> set to t, will exclude any messages with the "deleted" tag from
> searches.
> 
> Additionally, specifying "tag:deleted" in the search directly will
> override the exclusion and will included deleted messages in the
> search results.
> ---
>  emacs/notmuch.el   |8 
>  test/emacs |   42 
> 
>  .../notmuch-search-tag-inbox-deleted-excluded  |   24 +++
>  3 files changed, 74 insertions(+), 0 deletions(-)
>  create mode 100644 
> test/emacs.expected-output/notmuch-search-tag-inbox-deleted-excluded
> 
> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> index fde2377..c519687 100644
> --- a/emacs/notmuch.el
> +++ b/emacs/notmuch.el
> @@ -905,6 +905,11 @@ PROMPT is the string to prompt with."
>(read-from-minibuffer prompt nil keymap nil
>   'notmuch-query-history nil nil
>  
> +(defcustom notmuch-search-exclude-deleted nil
> +  "Exclude deleted messages (with \"deleted\" tag) from search results."
> +  :group 'notmuch
> +  :type 'boolean)
> +
>  ;;;###autoload
>  (defun notmuch-search (query &optional oldest-first target-thread 
> target-line continuation)
>"Run \"notmuch search\" with the given query string and display results.
> @@ -927,6 +932,9 @@ The optional parameters are used as follows:
>  (set 'notmuch-search-target-thread target-thread)
>  (set 'notmuch-search-target-line target-line)
>  (set 'notmuch-search-continuation continuation)
> +(when (and notmuch-search-exclude-deleted
> +(not (string-match "tag:deleted[ )]*" query)))

?is:? is a synonym for ?tag:? in searches ? so this section of the code
should look for it too.

-- 
Aaron Ecay


[PATCH 4/4] emacs: Use the new JSON reply format.

2012-01-08 Thread Aaron Ecay
Adam,

One comment below.

On Sun,  8 Jan 2012 00:52:42 -0700, Adam Wolfe Gordon  
wrote:
> From: Adam Wolfe Gordon 
> 
> Using the new JSON reply format allows emacs to quote HTML parts
> nicely by first parsing them with w3m, then quoting them. This is
> very useful for users who regularly receive HTML-only email.
> 
> The behavior for messages that contain plain text parts should be
> unchanged, except that an additional quoted line is added to the end
> of the reply message.  The test has been updated to reflect this.
> ---
>  emacs/notmuch-mua.el |   62 +++--
>  test/emacs   |1 +
>  2 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
> index 7114e48..7f894cb 100644
> --- a/emacs/notmuch-mua.el
> +++ b/emacs/notmuch-mua.el
> @@ -19,6 +19,7 @@
>  ;;
>  ;; Authors: David Edmondson 
>  
> +(require 'json)
>  (require 'message)
>  
>  (require 'notmuch-lib)
> @@ -71,27 +72,62 @@ list."
>   (push header message-hidden-headers)))
>   notmuch-mua-hidden-headers))
>  
> +(defun w3m-region (start end)) ;; From `w3m.el'.

What is the purpose of the above line?  If it is to make the compiler
aware of the function, you should use ?declare-function? instead.  Defun
will erase the original definition of the w3m-region function.

-- 
Aaron Ecay


[PATCH 0/4] Quoting HTML-only emails in replies redux

2012-01-08 Thread Aaron Ecay
On Sun,  8 Jan 2012 00:52:38 -0700, Adam Wolfe Gordon  
wrote:

[...]

> 
> There should probably be some customize variables for this in emacs, to 
> control
> (for example) whether to quote HTML parts and whether to prefer HTML or
> plaintext parts for quoting. Any suggestions for what should be customizable
> would be appreciated.

I think two variables should suffice: one (boolean) to control whether
to quote standalone text/html parts, and one to control which parts of a
multipart/alternative part to quote.  The latter should take possible
values 'text, 'html, and 'both.  This requires the emacs reply
functionality to distinguish between html parts that are part of a
multipart/alternative and those which are not, which (AFAICT) the
current code doesn?t do.

I haven?t tested the patch yet, but it looks very promising.  Thanks!

-- 
Aaron Ecay


[PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Austin Clements
> > @@ -927,6 +932,9 @@ The optional parameters are used as follows:
> >  (set 'notmuch-search-target-thread target-thread)
> >  (set 'notmuch-search-target-line target-line)
> >  (set 'notmuch-search-continuation continuation)
> > +(when (and notmuch-search-exclude-deleted
> > +  (not (string-match "tag:deleted[ )]*" query)))
> 
> ?is:? is a synonym for ?tag:? in searches ? so this section of the code
> should look for it too.

There are several other things that could also trip up this regexp.
xtag:deletedx would be falsely matched, as would a quoted phrase
containing "tag:deleted", while tag:"deleted" and tag:(deleted) would
incorrectly not be matched.  Getting this right is hard, though I'd be
happy with

  "\\<\\(tag\\|is\\):deleted\\>"

or maybe

  "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2"

Implicit exclusions like this were actually one of my target features
for the custom query parser, but I think hacking around that by
inspecting the query string is a fine interim solution.  (One of these
months I'll dust off the query parser, really!)


[PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Jameson Graef Rollins
On Sun, 8 Jan 2012 20:49:38 -0500, Austin Clements  wrote:
> > > @@ -927,6 +932,9 @@ The optional parameters are used as follows:
> > >  (set 'notmuch-search-target-thread target-thread)
> > >  (set 'notmuch-search-target-line target-line)
> > >  (set 'notmuch-search-continuation continuation)
> > > +(when (and notmuch-search-exclude-deleted
> > > +(not (string-match "tag:deleted[ )]*" query)))
> > 
> > ?is:? is a synonym for ?tag:? in searches ? so this section of the code
> > should look for it too.
> 
> There are several other things that could also trip up this regexp.
> xtag:deletedx would be falsely matched, as would a quoted phrase
> containing "tag:deleted", while tag:"deleted" and tag:(deleted) would
> incorrectly not be matched.

Thanks so much for the review, guys.  I should have mentioned in this
patch that the my regex skills are very weak, and that it was surely
incomplete.  I always forget about the is: prefix as well.

> Getting this right is hard, though I'd be happy with
> 
>   "\\<\\(tag\\|is\\):deleted\\>"

Every time I think I start to understand regex I am reminded that it's
black magic and I really know nothing.  For instance, I am not familiar
with "<" or ">", although they appear to be a "word" boundaries
(although I'm not sure how "word" is defined).  Also, why is all the \\
(double?)  escaping needed?  I'll certainly take your word for it,
though.

> or maybe
> 
>   "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2"

After staring at this for 10 minutes I think I'm getting the extra bits
here.  It matches an initial \", and then a second at the end if the
first matched.  That's clever.  Why 

  \\>\\2

instead of

 \\2\\>

?

I'm definitely confused by why so much apparent escaping is needed,
though.

> Implicit exclusions like this were actually one of my target features
> for the custom query parser, but I think hacking around that by
> inspecting the query string is a fine interim solution.  (One of these
> months I'll dust off the query parser, really!)

Very much looking forward to it!

jamie.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120108/3afe3c7f/attachment-0001.pgp>


[PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search

2012-01-08 Thread Austin Clements
Quoth Jameson Graef Rollins on Jan 08 at  6:34 pm:
> On Sun, 8 Jan 2012 20:49:38 -0500, Austin Clements  
> wrote:
> > > > @@ -927,6 +932,9 @@ The optional parameters are used as follows:
> > > >  (set 'notmuch-search-target-thread target-thread)
> > > >  (set 'notmuch-search-target-line target-line)
> > > >  (set 'notmuch-search-continuation continuation)
> > > > +(when (and notmuch-search-exclude-deleted
> > > > +  (not (string-match "tag:deleted[ )]*" query)))
> > > 
> > > ?is:? is a synonym for ?tag:? in searches ? so this section of the code
> > > should look for it too.
> > 
> > There are several other things that could also trip up this regexp.
> > xtag:deletedx would be falsely matched, as would a quoted phrase
> > containing "tag:deleted", while tag:"deleted" and tag:(deleted) would
> > incorrectly not be matched.
> 
> Thanks so much for the review, guys.  I should have mentioned in this
> patch that the my regex skills are very weak, and that it was surely
> incomplete.  I always forget about the is: prefix as well.
> 
> > Getting this right is hard, though I'd be happy with
> > 
> >   "\\<\\(tag\\|is\\):deleted\\>"
> 
> Every time I think I start to understand regex I am reminded that it's
> black magic and I really know nothing.  For instance, I am not familiar
> with "<" or ">", although they appear to be a "word" boundaries
> (although I'm not sure how "word" is defined).  Also, why is all the \\
> (double?)  escaping needed?  I'll certainly take your word for it,
> though.

I'm not positive, but I think \> matches on the transition from a
"word-constituent" character to a non-word-constituent character, as
defined by Emacs' active syntax table.

The slashes are all doubled because I was writing it as an Emacs
string for easy pasting (sorry, I should have been explicit about
that).  The regexp itself is

  \<\(tag\|is\):deleted\>

> > or maybe
> > 
> >   "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2"
> 
> After staring at this for 10 minutes I think I'm getting the extra bits
> here.  It matches an initial \", and then a second at the end if the
> first matched.  That's clever.  Why 

Exactly.

>   \\>\\2
> 
> instead of
> 
>  \\2\\>
> 
> ?

Okay, that can qualify as black magic.  The problem is that a " will
mess up the word-boundary matching because " isn't a word constituent
character.  So, if it is looking for a quote at the end, the \2 in
\2\> would match and consume the ", but then the \> wouldn't match.


  1   2   >