[PATCH v2 6/6] NEWS: update "Tag exclusion" section

2012-01-22 Thread Austin Clements
Quoth Pieter Praet on Jan 23 at  5:22 am:
> ---
>  NEWS |   14 ++
>  1 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index 2c2d9e9..a0b7929 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -13,10 +13,16 @@ Reply to sender
>  
>  Tag exclusion
>  
> -  Tags can be automatically excluded from search results unless they
> -  appear explicitly in a query.  By default, notmuch excludes the tags
> -  deleted and spam.  This can be changed using the new config setting
> -  search.auto_exclude_tags.
> +  Tags can be automatically excluded from search results by adding them
> +  to the new 'search.exclude_tags' option in the Notmuch config file.
> +
> +  This behaviour can be overridden by explicitly including an excluded
> +  tag in your query, for example:
> +
> +notmuch search $your_query and tag:$excluded_tag
> +
> +  Existing users will probably want to run "notmuch setup" again to add
> +  the new well-commented [search] section to the configuration file.

Should probably add something about the default for new
configurations.  This also gives existing users an idea of what to set
this to if they want to follow the conventions used by new
configurations.  Maybe just add

In new configurations, this defaults to "deleted" and "spam".

>  
>  Emacs Interface
>  ---


[PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup

2012-01-22 Thread Jameson Graef Rollins
On Mon, 23 Jan 2012 07:22:25 +, Jani Nikula  wrote:
> There really should be a definitive list of tags that are special to
> lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are
> recommended for specific purposes (like "new" as an intermediate tag
> before more sophisticated tagging), to avoid prolonged discussions like
> this.

Just to be clear: the lib doesn't assign any special meaning to any tag
(as it shouldn't).  The cli does, but only in the sense that it creates
config files that designate certain tags for certain operations by
default.  It's really in emacs where certain tags currently have
unconfigurable meanings ("inbox").

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/20120122/ff7f79aa/attachment.pgp>


[PATCH v2 5/6] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Austin Clements
Quoth Pieter Praet on Jan 23 at  5:22 am:
> Allow users to customize the search.exclude_tags option during setup.
> ---
>  notmuch-setup.c |   21 +
>  1 files changed, 21 insertions(+), 0 deletions(-)
> 
> diff --git a/notmuch-setup.c b/notmuch-setup.c
> index dcfa607..0d75adc 100644
> --- a/notmuch-setup.c
> +++ b/notmuch-setup.c
> @@ -133,6 +133,8 @@ notmuch_setup_command (unused (void *ctx),
>  int is_new;
>  const char **new_tags;
>  size_t new_tags_len;
> +const char **search_exclude_tags;
> +size_t search_exclude_tags_len;
>  
>  #define prompt(format, ...)  \
>  do { \
> @@ -208,6 +210,25 @@ notmuch_setup_command (unused (void *ctx),
>   g_ptr_array_free (tags, TRUE);
>  }
>  
> +
> +search_exclude_tags = notmuch_config_get_search_exclude_tags (config, 
> _exclude_tags_len);
> +
> +printf ("Tags to exclude when searching messages (separated by spaces) 
> [");
> +print_tag_list(search_exclude_tags, search_exclude_tags_len);

Missing space before paren.

> +prompt ("]: ");
> +
> +if (strlen (response)) {
> + GPtrArray *tags = parse_tag_list (ctx, response);
> +
> + notmuch_config_set_search_exclude_tags (config,
> + (const char **)
> + tags->pdata,

No newline is needed between the case and the value.

> + tags->len);
> +
> + g_ptr_array_free (tags, TRUE);
> +}
> +
> +
>  if (! notmuch_config_save (config)) {
>   if (is_new)
> welcome_message_post_setup ();


[PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup

2012-01-22 Thread Xavier Maillard

On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet  wrote:
> If the 'search.exclude_tags' option is missing from the config file,
> its value is automatically set to "deleted;spam;".  Taking PoLS/DWIM
> into account, this should probably only happen during setup.
> 
> This patch is actually Austin Clements' work:
>   id:"20120117203211.GQ16740 at mit.edu"

I do not think this is a sane default. As I told it in another post. I
do not expect notmuch to skew my search queries not that I specifically
asked.

/Xavier


[PATCH v3 2/2] search: Support automatic tag exclusions

2012-01-22 Thread Xavier Maillard
Hey Pieter,

On Thu, 19 Jan 2012 20:19:00 +0100, Pieter Praet  wrote:
> Nice feature!  I won't be using it myself, but I can imagine it being
> *very* useful for those who still feel the need to "delete" email :).

Adding a 'deleted' tag does not mean there will be a delete/purge
process ;) (currently I got 5k messages with the tag deleted ;). 

> Nitpicking:
> 

[ ... ]

>   So I'd like to suggest replacing all occurences of "auto_exclude_tags"
>   with "search_exclude_tags" (and simply "exclude_tags" in the args to
>   `_config_get_list' and `_config_set_list', of course).

+1

>   Unfortunately, this would also partially invalidate your recent NEWS
>   submission [2].
> 
> - If the 'search.exclude_tags' option is missing from the config file,
>   its value is automatically set to "deleted;spam;", which probably isn't
>   a sane default.  Luckily, you've already provided the solution [3].

I am against doing something /unsafe/ in the user's back. If there is no
option set intentionnaly by the user, there is nothing notmuch should
do -i.e no exclusion -

> - To make new users aware of the config option's existence, we should
>   prompt them to configure it during setup.

+1

/Xavier


[PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup

2012-01-22 Thread Jameson Graef Rollins
On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet  wrote:
> You definitely have a point, but then again, who are we to assume that
> the terms "deleted" and "spam" have the *exact* same meaning for
> everyone?  (also see id:"8739bbo0br.fsf at praet.org")

Hrm.  I'm not sure I buy this.  Words already have meanings.  If we're
going to start down a rabbit hole where we have to assume that users are
making up crazy alternate meanings for words, we're going to run into a
lot of problems.

Notmuch, or at least the emacs interface, already assumes a specific
meaning for certain terms, like most notably "inbox".  Given that we're
dealing with english here, I think we have to assume common usage
meanings for any of the words we're using to describe anything.

This argument breaks a little in regards to "delete" since we're not
actually deleting anything in the sense of rm'ing it form the
filesystem, so we're already changing the meaning a bit.  But see below.

> IMHO, this is one of those options that should remain disabled until
> *explicitly* set by the user.

Ok, but then we're back to the incredibly prolonged discussion we've
been having about adding "delete" keys.  If we disable this by default,
but add "delete" keys, the user might be in for a different surprise if
"deleted" messages keep showing up in searches.

Basically we have two options as I see it:

- add keys bindings to add "deleted" tags, and then *also* exclude
  "tag:deleted" by default.

- don't exclude anything by default, but then don't add any special keys
  to handle "deleted" tags.

There seemed to be a consensus forming that we in fact did want to add
the "deleted" key bindings.  If we do that, then I think we should
generate the config file to exclude "deleted" tags by default.

jamie.

PS: when I say "exclude tags by default" I actually mean that the
setting should be added to the config file upon (re)generation.  Nothing
should be excluded if nothing is set in the config file.
-- 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/20120122/d2550237/attachment.pgp>


[PATCH v2 3/3] show: Introduce mime_node formatter callback

2012-01-22 Thread Austin Clements
This callback is the gateway to the new mime_node_t-based formatters.
This maintains backwards compatibility so the formatters can be
transitioned one at a time.  Once all formatters are converted, the
formatter structure can be reduced to only message_set_{start,sep,end}
and part, most of show_message can be deleted, and all of
show-message.c can be deleted.
---
 notmuch-client.h |6 ++
 notmuch-reply.c  |2 +-
 notmuch-show.c   |   23 +++
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index abfe5d3..59606b4 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -62,8 +62,14 @@
 #define STRINGIFY(s) STRINGIFY_(s)
 #define STRINGIFY_(s) #s

+struct mime_node;
+struct notmuch_show_params;
+
 typedef struct notmuch_show_format {
 const char *message_set_start;
+void (*part) (const void *ctx,
+ struct mime_node *node, int indent,
+ struct notmuch_show_params *params);
 const char *message_start;
 void (*message) (const void *ctx,
 notmuch_message_t *message,
diff --git a/notmuch-reply.c b/notmuch-reply.c
index bf67960..f55b1d2 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -31,7 +31,7 @@ static void
 reply_part_content (GMimeObject *part);

 static const notmuch_show_format_t format_reply = {
-"",
+"", NULL,
"", NULL,
"", NULL, reply_headers_message_part, ">\n",
"",
diff --git a/notmuch-show.c b/notmuch-show.c
index 682aa71..8185b02 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -42,7 +42,7 @@ static void
 format_part_end_text (GMimeObject *part);

 static const notmuch_show_format_t format_text = {
-"",
+"", NULL,
"\fmessage{ ", format_message_text,
"\fheader{\n", format_headers_text, 
format_headers_message_part_text, "\fheader}\n",
"\fbody{\n",
@@ -89,7 +89,7 @@ static void
 format_part_end_json (GMimeObject *part);

 static const notmuch_show_format_t format_json = {
-"[",
+"[", NULL,
"{", format_message_json,
"\"headers\": {", format_headers_json, 
format_headers_message_part_json, "}",
", \"body\": [",
@@ -110,7 +110,7 @@ format_message_mbox (const void *ctx,
 unused (int indent));

 static const notmuch_show_format_t format_mbox = {
-"",
+"", NULL,
 "", format_message_mbox,
 "", NULL, NULL, "",
 "",
@@ -129,7 +129,7 @@ static void
 format_part_content_raw (GMimeObject *part);

 static const notmuch_show_format_t format_raw = {
-"",
+"", NULL,
"", NULL,
"", NULL, format_headers_message_part_text, "\n",
 "",
@@ -850,6 +850,21 @@ show_message (void *ctx,
  int indent,
  notmuch_show_params_t *params)
 {
+if (format->part) {
+   void *local = talloc_new (ctx);
+   mime_node_t *root, *part;
+
+   if (mime_node_open (local, message, params->cryptoctx, params->decrypt,
+   ) != NOTMUCH_STATUS_SUCCESS)
+   goto DONE;
+   part = mime_node_seek_dfs (root, params->part < 0 ? 0 : params->part);
+   if (part)
+   format->part (local, part, indent, params);
+  DONE:
+   talloc_free (local);
+   return;
+}
+
 if (params->part <= 0) {
fputs (format->message_start, stdout);
if (format->message)
-- 
1.7.7.3



[PATCH v2 2/3] show: Use consistent header ordering in the text format

2012-01-22 Thread Austin Clements
Previously, top-level message headers were printed as Subject, From,
To, Date, while embedded message headers were printed From, To,
Subject, Date.  This makes both cases use the former order and updates
the tests accordingly.

Strangely, the raw format also uses this function, so this also fixes
the two raw format tests affected by this change.
---
 notmuch-show.c |2 +-
 test/multipart |   12 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 7b40568..682aa71 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -364,6 +364,7 @@ format_headers_message_part_text (GMimeMessage *message)
 InternetAddressList *recipients;
 const char *recipients_string;

+printf ("Subject: %s\n", g_mime_message_get_subject (message));
 printf ("From: %s\n", g_mime_message_get_sender (message));
 recipients = g_mime_message_get_recipients (message, 
GMIME_RECIPIENT_TYPE_TO);
 recipients_string = internet_address_list_to_string (recipients, 0);
@@ -375,7 +376,6 @@ format_headers_message_part_text (GMimeMessage *message)
 if (recipients_string)
printf ("Cc: %s\n",
recipients_string);
-printf ("Subject: %s\n", g_mime_message_get_subject (message));
 printf ("Date: %s\n", g_mime_message_get_date_as_string (message));
 }

diff --git a/test/multipart b/test/multipart
index f83526b..2dd73f5 100755
--- a/test/multipart
+++ b/test/multipart
@@ -121,9 +121,9 @@ Date: Fri, 05 Jan 2001 15:43:57 +
 part{ ID: 2, Content-type: multipart/mixed
 part{ ID: 3, Content-type: message/rfc822
 header{
+Subject: html message
 From: Carl Worth 
 To: cworth at cworth.org
-Subject: html message
 Date: Fri, 05 Jan 2001 15:42:57 +
 header}
 body{
@@ -162,9 +162,9 @@ cat OU
 cat OUT
 # output should *not* include newline
 echo >>OUTPUT
 cat OUTPUT
 cat 

[PATCH v2 1/3] mime node: Record depth-first part numbers

2012-01-22 Thread Austin Clements
This makes the part numbers readily accessible to formatters.
Hierarchical part numbering would be a more natural and efficient fit
for MIME and may be the way to go in the future, but depth-first
numbering maintains compatibility with what we currently do.
---
 mime-node.c  |   37 ++---
 notmuch-client.h |   14 +-
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index 27077f7..025c537 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -112,6 +112,10 @@ mime_node_open (const void *ctx, notmuch_message_t 
*message,
 root->nchildren = 1;
 root->ctx = mctx;

+root->part_num = 0;
+root->next_child = 0;
+root->next_part_num = 1;
+
 *root_out = root;
 return NOTMUCH_STATUS_SUCCESS;

@@ -137,7 +141,7 @@ _signature_validity_free (GMimeSignatureValidity **proxy)
 #endif

 static mime_node_t *
-_mime_node_create (const mime_node_t *parent, GMimeObject *part)
+_mime_node_create (mime_node_t *parent, GMimeObject *part)
 {
 mime_node_t *node = talloc_zero (parent, mime_node_t);
 GError *err = NULL;
@@ -150,6 +154,8 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
talloc_free (node);
return NULL;
 }
+node->parent = parent;
+node->part_num = node->next_part_num = -1;

 /* Deal with the different types of parts */
 if (GMIME_IS_PART (part)) {
@@ -267,9 +273,10 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 }

 mime_node_t *
-mime_node_child (const mime_node_t *parent, int child)
+mime_node_child (mime_node_t *parent, int child)
 {
 GMimeObject *sub;
+mime_node_t *node;

 if (!parent || child < 0 || child >= parent->nchildren)
return NULL;
@@ -287,7 +294,31 @@ mime_node_child (const mime_node_t *parent, int child)
INTERNAL_ERROR ("Unexpected GMimeObject type: %s",
g_type_name (G_OBJECT_TYPE (parent->part)));
 }
-return _mime_node_create (parent, sub);
+node = _mime_node_create (parent, sub);
+
+if (child == parent->next_child && parent->next_part_num != -1) {
+   /* We're traversing in depth-first order.  Record the child's
+* depth-first numbering. */
+   node->part_num = parent->next_part_num;
+   node->next_part_num = node->part_num + 1;
+
+   /* Drop the const qualifier because these are internal fields
+* whose mutability doesn't affect the interface. */
+   parent->next_child++;
+   parent->next_part_num = -1;
+
+   if (node->nchildren == 0) {
+   /* We've reached a leaf, so find the parent that has more
+* children and set it up to number its next child. */
+   mime_node_t *it = node;
+   while (it && it->next_child == it->nchildren)
+   it = it->parent;
+   if (it)
+   it->next_part_num = node->part_num + 1;
+   }
+}
+
+return node;
 }

 static mime_node_t *
diff --git a/notmuch-client.h b/notmuch-client.h
index 9c1d383..abfe5d3 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -297,6 +297,13 @@ typedef struct mime_node {
 /* The number of children of this part. */
 int nchildren;

+/* The parent of this node or NULL if this is the root node. */
+struct mime_node *parent;
+
+/* The depth-first part number of this child if the MIME tree is
+ * being traversed in depth-first order, or -1 otherwise. */
+int part_num;
+
 /* True if decryption of this part was attempted. */
 notmuch_bool_t decrypt_attempted;
 /* True if decryption of this part's child succeeded.  In this
@@ -324,6 +331,11 @@ typedef struct mime_node {
 /* Internal: For successfully decrypted multipart parts, the
  * decrypted part to substitute for the second child. */
 GMimeObject *decrypted_child;
+
+/* Internal: The next child for depth-first traversal and the part
+ * number to assign it (or -1 if unknown). */
+int next_child;
+int next_part_num;
 } mime_node_t;

 /* Construct a new MIME node pointing to the root message part of
@@ -356,7 +368,7 @@ mime_node_open (const void *ctx, notmuch_message_t *message,
  * an error message on stderr).
  */
 mime_node_t *
-mime_node_child (const mime_node_t *parent, int child);
+mime_node_child (mime_node_t *parent, int child);

 /* Return the nth child of node in a depth-first traversal.  If n is
  * 0, returns node itself.  Returns NULL if there is no such part. */
-- 
1.7.7.3



[PATCH v2 0/3] Second step of 'show' rewrite

2012-01-22 Thread Austin Clements
This revision addresses Jani's comments.  It removes some
const-stripping casts (at the cost of dropping a const from the API),
fixes a delayed free, and cleans up some aesthetics.



[PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Austin Clements
Quoth Mark Walters on Jan 23 at  1:13 am:
> On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements  
> wrote:
> > Quoth myself on Jan 20 at 12:18 pm:
> > > Quoth Mark Walters on Jan 20 at 12:10 am:
> > > > 
> > > > Ok Having said this is trivial I have found a problem. What should
> > > > notmuch do if you do something like
> > > > 
> > > > notmuch show id:
> > > > and that message is marked with a deleted tag? To be consistent with the
> > > > other cases (where a deleted message is in a matched thread) we might
> > > > want to return the message with the not-matched flag set (eg in
> > > > JSON). But my patch doesn't, as it never even sees the thread since it
> > > > doesn't match.
> > > > 
> > > > Looking at notmuch-show.c I think we should not apply the exclude tags
> > > > to do_show_single, but usually should apply it to do_show. One solution
> > > > which is simple and is at least close to right would be to get do_show
> > > > to return the number of threads found. If this is zero then retry the
> > > > query without the excludes (possible setting the match_flag to zero on
> > > > each message since we know it does not match)
> > > > 
> > > > This is not a completely correct solution as if you ask notmuch-show to
> > > > show more than one thread it might  threads which only contain deleted
> > > > messages.
> > > > 
> > > > I can't see other good possibilities without slowing down the normal
> > > > path a lot (eg find all threads that match the original query and then
> > > > apply the argument above).
> > > > 
> > > > Any thoughts?
> > > 
> > > Oh dear.
> > > 
> > > Well, here's one idea.  Instead of doing a single thread query in
> > > show, do a thread query without the exclusions and then a message
> > > query with the exclusions.  Output all of the messages from the first
> > > query, but use the results of the second query to determine which
> > > messages are "matched".  The same could be accomplished in the library
> > > somewhat more efficiently, but it's not obvious to me what the API
> > > would be.
> > 
> > Here's a slightly crazier idea that's more library-invasive than the
> > original approach, but probably better in the long run.
> > 
> > Have notmuch_query_search_* return everything and make exclusion a
> > message flag like NOTMUCH_MESSAGE_FLAG_MATCH.  Tweak the definition of
> > "matched" to mean "matched and not excluded" (specifically, a message
> > would have the match flag or the excluded flag or neither, but not
> > both).  Search would skip threads with zero matched messages and I
> > think show would Just Work.
> > 
> > I can think of two ways to implement this.  notmuch_query_search_*
> > could perform both the original query and the query with exclusions
> > and use the docid set from the second to compute the "excluded"
> > message flag.  Alternatively, it could examine the tags of each
> > message directly to compute the flag.  The latter is probably easier
> > to implement, but probably slower.
> > 
> > Thoughts?
> 
> I have now thought about this some more and think I understand your idea
> (and how it would work) rather better now. 
> 
> I would suggest one small change: the flags for the messages returned
> should be "independent": so a message can match the query or not, and it
> can be excluded or not, with all 4 combinations being possible. (The
> consumer of notmuch_query_search_* would extract the information it
> wanted.)

I'd initially approached it this way, but went with redefining a
"matched" messages because it had much less impact on the API.  For
example, with the redefined "match",
notmuch_thread_get_matched_messages still does the right thing for
search and things like the thread subject can still be based on
"matched" messages.  If we orthongonalize these flags, then we at
least need to count matched non-excluded messages and provide an API
to access this (while I don't have a solid argument against such an
API it just seems weirdly specific to me).

My other concern is performance.  In thread queries, marking
non-matched messages as excluded would require either an extra query
per thread or a single query to match all excluded messages (not
filtered by the primary query).  The former is prohibitive, though the
latter might be acceptable (that might depend on how many things
people mark as spam or deleted).  If the cost is too high, this
suggests that we shouldn't mark non-matched messages as excluded, but
then we're back to effectively having three levels of matching: not
matched, matched but not excluded, and matched but excluded.

> I have thought about some implementation ideas but I think sorting is
> going to be the deciding factor: what order should
> notmuch_query_search_* return messages/threads? 

Yes.  This is exactly what I've been puzzling over, too.

> For notmuch_query_search_messages either it returns them all together
> with the excluded messages marked, or returns all included ones, and
> then all excluded one.

I would prefer them 

[PATCH 1/3] mime node: Record depth-first part numbers

2012-01-22 Thread Austin Clements
Quoth myself on Jan 18 at  9:12 pm:
> Quoth Jani Nikula on Jan 19 at 12:25 am:
> > FWIW, I'm not a big fan of casting away const. Either it is const, or it
> > isn't. Not very many places would be affected if you dropped the const
> > qualifier from the related interface(s) altogether, and things would
> > look cleaner here. But I suppose this is a matter of taste.
> 
> I'm not particularly happy with this either.  Unfortunately, dropping
> the const here affects a surprising number of places, including the
> entire MIME node API.

I've changed my mind and removed a few consts so that this funny cast
isn't necessary.  (It also turned out that when I tried this before,
I'd given up just a smidgen before removing enough consts to make it
work.)

> I think that, at a deep level, depth-first numbering simply doesn't
> resonate with an extremely hierarchical API like this and that
> dissonance is going to have to focus somewhere.  There have been
> discussions of switching to hierarchical part numbering before (in
> particular, because depth-first numbering is unstable with encrypted
> parts) and I'll probably restart those after all of this is done.

I have not, however, changed my mind about this.


[PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Mark Walters

On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements  wrote:
> Quoth myself on Jan 20 at 12:18 pm:
> > Quoth Mark Walters on Jan 20 at 12:10 am:
> > > 
> > > Ok Having said this is trivial I have found a problem. What should
> > > notmuch do if you do something like
> > > 
> > > notmuch show id:
> > > and that message is marked with a deleted tag? To be consistent with the
> > > other cases (where a deleted message is in a matched thread) we might
> > > want to return the message with the not-matched flag set (eg in
> > > JSON). But my patch doesn't, as it never even sees the thread since it
> > > doesn't match.
> > > 
> > > Looking at notmuch-show.c I think we should not apply the exclude tags
> > > to do_show_single, but usually should apply it to do_show. One solution
> > > which is simple and is at least close to right would be to get do_show
> > > to return the number of threads found. If this is zero then retry the
> > > query without the excludes (possible setting the match_flag to zero on
> > > each message since we know it does not match)
> > > 
> > > This is not a completely correct solution as if you ask notmuch-show to
> > > show more than one thread it might  threads which only contain deleted
> > > messages.
> > > 
> > > I can't see other good possibilities without slowing down the normal
> > > path a lot (eg find all threads that match the original query and then
> > > apply the argument above).
> > > 
> > > Any thoughts?
> > 
> > Oh dear.
> > 
> > Well, here's one idea.  Instead of doing a single thread query in
> > show, do a thread query without the exclusions and then a message
> > query with the exclusions.  Output all of the messages from the first
> > query, but use the results of the second query to determine which
> > messages are "matched".  The same could be accomplished in the library
> > somewhat more efficiently, but it's not obvious to me what the API
> > would be.
> 
> Here's a slightly crazier idea that's more library-invasive than the
> original approach, but probably better in the long run.
> 
> Have notmuch_query_search_* return everything and make exclusion a
> message flag like NOTMUCH_MESSAGE_FLAG_MATCH.  Tweak the definition of
> "matched" to mean "matched and not excluded" (specifically, a message
> would have the match flag or the excluded flag or neither, but not
> both).  Search would skip threads with zero matched messages and I
> think show would Just Work.
> 
> I can think of two ways to implement this.  notmuch_query_search_*
> could perform both the original query and the query with exclusions
> and use the docid set from the second to compute the "excluded"
> message flag.  Alternatively, it could examine the tags of each
> message directly to compute the flag.  The latter is probably easier
> to implement, but probably slower.

I really like the idea of returning two flags. I think your first
suggestion works better for sorting reasons: we want to return a thread
which has a match-not-excluded message and also a match-excluded message
to be sorted based on the match-not-excluded message. Hence in
notmuch_query_search_threads we can create the list of docids to iterate
over as the list generated by query with exclusions followed by the list
without exclusions.  This list contains lots of messages twice but that
doesn't matter since we have to check whether we have already output
the message in an earlier thread anyway. 

Incidentally, it might not take very much more code to allow
notmuch_query_search_threads to take two arbitrary queries and return
all threads which match the first case but mark as matched those that
match the second: i.e. a step on the way towards "thread based and".

Best wishes

Mark




ignore folders patch?

2012-01-22 Thread Tomi Ollila
On Sun, 22 Jan 2012 12:32:12 +0100, Fabio Zanini  
wrote:
> Hi!
> 
> This is my first message to the list. In 2010 a patch was developed that
> enabled notmuch new to ignore certain subdirectories of the mail folder:
> 
> http://notmuchmail.org/pipermail/notmuch/2010/003170.html
> 
> However, I cannot find any reference to it in the git history, and it
> does not seem to have been implemented.
> 
> This feature seems to be relevant, what would you think of reviving it
> and including it into the codebase? I could try to update the patch
> myself.

  I also attempted to do something about it; check

   id:"1315949524-4948-1-git-send-email-tomi.ollila at iki.fi"

Partly due to these issues did organized my mail directories
a bit differently and dropped this thing...

> Cheers,
> Fabio

Tomi


[PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup

2012-01-22 Thread Jameson Graef Rollins
On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard  
wrote:
> 
> On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet  wrote:
> > If the 'search.exclude_tags' option is missing from the config file,
> > its value is automatically set to "deleted;spam;".  Taking PoLS/DWIM
> > into account, this should probably only happen during setup.
> > 
> > This patch is actually Austin Clements' work:
> >   id:"20120117203211.GQ16740 at mit.edu"
> 
> I do not think this is a sane default. As I told it in another post. I
> do not expect notmuch to skew my search queries not that I specifically
> asked.

Hi, Xavier.  Do you currently mark things as "deleted" or "spam"?  If
not, this would have no affect on your search results.  If you do, do
you currently expect those messages to show up in searches?  If so, why
did you mark them as "deleted" or "spam" to begin with?

I agree with your point in principle (ie. I don't generally want my
searches tampered with behind the scenes) but the issue here is about
messages that have been explicitly tagged as a form of "trash".  Trash
is by it's nature something you're trying to get rid of.  If you wanted
to find something in the future, why would you put it in the trash in
the first place?

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/20120122/00f75357/attachment.pgp>


[PATCH 0/3] Second step of 'show' rewrite

2012-01-22 Thread Jameson Graef Rollins
On Wed, 18 Jan 2012 15:28:24 -0500, Austin Clements  wrote:
> This adds support for self-recursive message formatters, while
> maintaining backwards compatibility with old style formatters.  After
> this, each format can be converted to the new style individually and,
> once they're all converted, a bunch of code can be deleted.
> 
> These three patches are independent and can be pushed in any order.  I
> put them in a series because pushing them before any formatter
> rewrites will simplify dependencies between the individual formatter
> rewrites.

Hey, Austin.  I just looked through these patches and tested them out
and they look good.  Jani's comments are more incisive than anything I
could come up with.  +1 on the series, and I'm looking forward to the
next phase.

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/20120122/6f01b7ff/attachment.pgp>


[PATCH] lib: Save filenames for files detected as "not an email file" in the database.

2012-01-22 Thread Jani Nikula
On Sat, 21 Jan 2012 18:49:19 -0500, Austin Clements  wrote:
> Quoth Jani Nikula on Jan 22 at  1:00 am:
> > On Fri, 20 Jan 2012 17:00:27 -0500, Austin Clements  
> > wrote:
> > > Later runs of "notmuch new" won't scan these files again and won't
> > > print warnings.
> > > 
> > > Various programs (Dovecot, in my case) store indexes and caches and
> > > such in the maildir.  Without this, notmuch persistently complains
> > > about such files.
> > 
> > Overall, sounds good and doing this automagically is nice. Superficially
> > the code looks sensible, but I didn't really dig into it. A few nasty
> > questions instead:
> > 
> > What happens if you delete a non-email file? Does the entry stay in the
> > database?
> 
> Phooey.  I thought this worked, but you're right that it doesn't (I
> even wrote a test for this, but the test was based on a false
> assumption).  Non-email files do get returned by the directory
> iterator, so without any changes, notmuch new will notice that they're
> gone.  What I missed is that it then uses
> notmuch_database_find_message_by_filename to find the "message" and
> remove the filename, which won't work since there's no message to
> find.
> 
> I'll have to think about this more.

Sorry about that...

This feature has considerable overlap with file/subdirectory exclusion,
most recently referred to in id:"20120122113212.GA7084 at X200". I like the
way your approach is automatic, but doing it manually with configurable
exclusions has certain explicitness to it, and altogether avoids the
problems here, don't you think? There apparently also are people who
wouldn't want notmuch to index some valid email files for one reason or
another.

I haven't thought this through, but what if the exclude/ignore feature
had both the option to specify explicit files/subdirs (patterns like
.gitignore?) that are ignored, and some sort of "auto" option you could
enable to ignore all non-email files without warnings? This would
obviously all happen in the cli.

That probably does not make your thinking any easier, I'm afraid... but
perhaps it provides another angle.


BR,
Jani.


> 
> > What happens if you replace a non-email file with an email file?
> 
> It will not notice because notmuch new only inspects directory mtimes.
> This would require checking the mtimes of every non-email in the
> database on every notmuch new.
> 
> > Does it matter what happens above?
> > 
> > These are corner cases, but what remains in TODO suggests that it would
> > be difficult to debug and figure out if the above ever did happen to
> > someone.
> 
> Yes.  It's possible this needs to get a search syntax before it is
> acceptable for general use.
> 
> > BR,
> > Jani.


[PATCH] python: fix error handling

2012-01-22 Thread Justus Winter
Before 3434d1940 the return values of libnotmuch functions were
declared as c_void_p and the code checking for errors compared the
returned value to None, which is the ctypes equivalent of a NULL
pointer.

But said commit wrapped all the data types in python classes and the
semantic changed in a subtle way. If a function returns NULL, the
wrapped python value is falsish, but no longer equal to None.

Backported from master to 0.11.
---
 bindings/python/notmuch/database.py |   16 
 bindings/python/notmuch/filename.py |2 +-
 bindings/python/notmuch/message.py  |6 +++---
 bindings/python/notmuch/tag.py  |2 +-
 bindings/python/notmuch/thread.py   |6 +++---
 5 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/bindings/python/notmuch/database.py 
b/bindings/python/notmuch/database.py
index 7923f76..0074ba3 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -168,7 +168,7 @@ class Database(object):

 res = Database._create(_str(path), Database.MODE.READ_WRITE)

-if res is None:
+if not res:
 raise NotmuchError(
 message="Could not create the specified database")
 self._db = res
@@ -188,7 +188,7 @@ class Database(object):
 """
 res = Database._open(_str(path), mode)

-if res is None:
+if not res:
 raise NotmuchError(message="Could not open the specified database")
 self._db = res

@@ -645,7 +645,7 @@ class Query(object):
 self._db = db
 # create query, return None if too little mem available
 query_p = Query._create(db.db_p, _str(querystr))
-if query_p is None:
+if not query_p:
 raise NullPointerError
 self._query = query_p

@@ -679,7 +679,7 @@ class Query(object):
 self._assert_query_is_initialized()
 threads_p = Query._search_threads(self._query)

-if threads_p is None:
+if not threads_p:
 raise NullPointerError
 return Threads(threads_p, self)

@@ -693,7 +693,7 @@ class Query(object):
 self._assert_query_is_initialized()
 msgs_p = Query._search_messages(self._query)

-if msgs_p is None:
+if not msgs_p:
 raise NullPointerError
 return Messages(msgs_p, self)

@@ -759,7 +759,7 @@ class Directory(object):
 def _assert_dir_is_initialized(self):
 """Raises a NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
 if dir_p is None"""
-if self._dir_p is None:
+if not self._dir_p:
 raise NotmuchError(STATUS.NOT_INITIALIZED)

 def __init__(self, path, dir_p, parent):
@@ -920,7 +920,7 @@ class Filenames(object):
 _move_to_next.restype = None

 def next(self):
-if self._files_p is None:
+if not self._files_p:
 raise NotmuchError(STATUS.NOT_INITIALIZED)

 if not self._valid(self._files_p):
@@ -946,7 +946,7 @@ class Filenames(object):
  # NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
  for file in files: print file
 """
-if self._files_p is None:
+if not self._files_p:
 raise NotmuchError(STATUS.NOT_INITIALIZED)

 i = 0
diff --git a/bindings/python/notmuch/filename.py 
b/bindings/python/notmuch/filename.py
index a7cd7e6..f7313ec 100644
--- a/bindings/python/notmuch/filename.py
+++ b/bindings/python/notmuch/filename.py
@@ -69,7 +69,7 @@ class Filenames(object):
  reference to it, so we can automatically delete the db object
  once all derived objects are dead.
 """
-if files_p is None:
+if not files_p:
 raise NotmuchError(STATUS.NULL_POINTER)

 self._files = files_p
diff --git a/bindings/python/notmuch/message.py 
b/bindings/python/notmuch/message.py
index ce8e718..5540df3 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -116,7 +116,7 @@ class Messages(object):
 :TODO: Make the iterator work more than once and cache the tags in
the Python object.(?)
 """
-if msgs_p is None:
+if not msgs_p:
 raise NotmuchError(STATUS.NULL_POINTER)

 self._msgs = msgs_p
@@ -321,7 +321,7 @@ class Message(object):
   automatically delete the parent object once all derived
   objects are dead.
 """
-if msg_p is None:
+if not msg_p:
 raise NotmuchError(STATUS.NULL_POINTER)
 self._msg = msg_p
 #keep reference to parent, so we keep it alive
@@ -380,7 +380,7 @@ class Message(object):

 msgs_p = Message._get_replies(self._msg)

-if msgs_p is None:
+if not msgs_p:
 return None

 return Messages(msgs_p, self)
diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py
index 2fb7d32..4881db9 100644
--- 

[PATCH 2/3] emacs: Don't return the button from `notmuch-show-insert-part-header'.

2012-01-22 Thread Jameson Graef Rollins
On Fri, 20 Jan 2012 09:43:31 +, David Edmondson  wrote:
> Instead, allow the caller to specify some parameters for the
> button. Rework `notmuch-show-insert-part-multipart/signed' and
> `notmuch-show-insert-part-multipart/encrypted' accordingly, moving
> most of the code into a common
> `notmuch-show-insert-part-multipart/signed-or-encrypted' to reduce
> duplication.

Hi, David.  A couple of issues with this patch:

This patch seems to include multiple distinct changes.  There is a
change to notmuch-show-insert-part-header, but a seemingly unrelated
change to the insertion of signed/encrypted part buttons.  They should
be in separate patches.

I'm also not sure I understand why the proposed changes to the
signed/encrypted button insertion functions are necessary or desired.
Was there a problem with the logic as it was?  What is gained by having
one function filled with special casing to handle two things, rather
than having two distinct functions?

Finally, this patch throws out all the changes from the previous patch,
making the previous patch superfluous.

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/20120122/4fdd2c00/attachment.pgp>


[PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Austin Clements
Quoth myself on Jan 20 at 12:18 pm:
> Quoth Mark Walters on Jan 20 at 12:10 am:
> > 
> > Ok Having said this is trivial I have found a problem. What should
> > notmuch do if you do something like
> > 
> > notmuch show id:
> > and that message is marked with a deleted tag? To be consistent with the
> > other cases (where a deleted message is in a matched thread) we might
> > want to return the message with the not-matched flag set (eg in
> > JSON). But my patch doesn't, as it never even sees the thread since it
> > doesn't match.
> > 
> > Looking at notmuch-show.c I think we should not apply the exclude tags
> > to do_show_single, but usually should apply it to do_show. One solution
> > which is simple and is at least close to right would be to get do_show
> > to return the number of threads found. If this is zero then retry the
> > query without the excludes (possible setting the match_flag to zero on
> > each message since we know it does not match)
> > 
> > This is not a completely correct solution as if you ask notmuch-show to
> > show more than one thread it might  threads which only contain deleted
> > messages.
> > 
> > I can't see other good possibilities without slowing down the normal
> > path a lot (eg find all threads that match the original query and then
> > apply the argument above).
> > 
> > Any thoughts?
> 
> Oh dear.
> 
> Well, here's one idea.  Instead of doing a single thread query in
> show, do a thread query without the exclusions and then a message
> query with the exclusions.  Output all of the messages from the first
> query, but use the results of the second query to determine which
> messages are "matched".  The same could be accomplished in the library
> somewhat more efficiently, but it's not obvious to me what the API
> would be.

Here's a slightly crazier idea that's more library-invasive than the
original approach, but probably better in the long run.

Have notmuch_query_search_* return everything and make exclusion a
message flag like NOTMUCH_MESSAGE_FLAG_MATCH.  Tweak the definition of
"matched" to mean "matched and not excluded" (specifically, a message
would have the match flag or the excluded flag or neither, but not
both).  Search would skip threads with zero matched messages and I
think show would Just Work.

I can think of two ways to implement this.  notmuch_query_search_*
could perform both the original query and the query with exclusions
and use the docid set from the second to compute the "excluded"
message flag.  Alternatively, it could examine the tags of each
message directly to compute the flag.  The latter is probably easier
to implement, but probably slower.

Thoughts?


ignore folders patch?

2012-01-22 Thread Fabio Zanini
Hi!

This is my first message to the list. In 2010 a patch was developed that
enabled notmuch new to ignore certain subdirectories of the mail folder:

http://notmuchmail.org/pipermail/notmuch/2010/003170.html

However, I cannot find any reference to it in the git history, and it
does not seem to have been implemented.

This feature seems to be relevant, what would you think of reviving it
and including it into the codebase? I could try to update the patch
myself.

Cheers,
Fabio


[PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Austin Clements
Quoth Mark Walters on Jan 22 at 12:38 am:
> 
> On Fri, 20 Jan 2012 12:18:01 -0500, Austin Clements  
> wrote:
> > 
> > Oh dear.
> > 
> > Well, here's one idea.  Instead of doing a single thread query in
> > show, do a thread query without the exclusions and then a message
> > query with the exclusions.  Output all of the messages from the first
> > query, but use the results of the second query to determine which
> > messages are "matched".  The same could be accomplished in the library
> > somewhat more efficiently, but it's not obvious to me what the API
> > would be.
> 
> I have been thinking about this and one question is what should the sort
> order be? If I understand it correctly notmuch sorts the threads
> by the oldest/newest matching message, so the "correct" behaviour if no
> message matches is unclear. Perhaps all threads with a matching
> non-excluded message sorted by the matching-non-excluded message
> followed by all threads that match only on excluded messages with sort
> based on the matching excluded message?

I don't think show sorts in any particular way.  Or are you saying
that search also needs to know the difference between excluded and
non-excluded matched messages?


[PATCH 4/4] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Austin Clements
Quoth Pieter Praet on Jan 22 at  7:55 am:
> On Thu, 19 Jan 2012 23:19:02 -0500, Austin Clements  
> wrote:
> > [...]
> > Hah, okay.  How about this as an initial minor refactoring of the code
> > for new.tags?
> > [...]
> 
> Great, thanks!
> 
> 
> Would the following commit message be satisfactory? :
> 
>   #+begin_quote
> setup: move tag printing and parsing into separate functions
> 
> * notmuch-setup.c (notmuch_setup_command):
>   Break tag printing and response parsing out into separate functions
>   called `print_tag_list' respectively `parse_tag_list', for reuse
>   with the 'search.exclude_tags' option.
>   #+end_quote
> 
> (if not, please suggest an alternative; it'll be your name at the top)

Sure.


[PATCH v3 5/5] emacs: Use message-cite-original in reply

2012-01-22 Thread Adam Wolfe Gordon
Use message-mode's message-cite-original function to create the
quoted body for reply messages. In order to make this act like the
existing notmuch defaults, you will need to set the following in
your emacs configuration:

message-citation-line-format "On %a, %d %b %Y, %f wrote:"
message-citation-line-function 'message-insert-formatted-citation-line

The test has been updated to reflect the (ugly) emacs default.
---

Here is an alternate version of the patch, which uses message-cite-original.

I suggest people try out this version and see if the behavior is
acceptable with some configuration tweaks. If it is, then we can
work on implementing the notmuch-emacs config file idea, and go
with this version. As I mentioned, the one thing I haven't figured
out how to do with configuration is make message-cite-original fill
the quoted message. This would probably be a dealbreaker for me, but
I suspect it can be done somehow with the right combination of hooks.

 emacs/notmuch-mua.el |   32 +++-
 test/emacs   |3 ++-
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 5ae0ccf..45c314d 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -21,6 +21,7 @@

 (require 'json)
 (require 'message)
+(require 'format-spec)

 (require 'notmuch-lib)
 (require 'notmuch-address)
@@ -134,19 +135,24 @@ list."
  (forward-line -1)
(goto-char (point-max)))

-  (insert (format "On %s, %s wrote:\n"
- (cdr (assq 'date original-headers))
- (cdr (assq 'from original-headers
-
-  (if plain-parts
- (mapc (lambda (part) (notmuch-mua-insert-part-quoted part)) 
plain-parts)
-   (mapc (lambda (part)
-   (notmuch-mua-insert-part-quoted (notmuch-mua-parse-html-part 
part)))
- html-parts))
-
-  (push-mark))
-(set-buffer-modified-p nil))
-
+  (let ((from (cdr (assq 'from original-headers)))
+   (date (cdr (assq 'date original-headers)))
+   (start (point)))
+
+   (insert "From: " from "\n")
+   (insert "Date: " date "\n\n")
+  
+   (if plain-parts
+   (mapc 'insert plain-parts)
+ (mapc (lambda (part)
+ (insert (notmuch-mua-parse-html-part part)))
+   html-parts))
+   (push-mark)
+   (goto-char start)
+   (message-cite-original
+
+  (push-mark)
+  (set-buffer-modified-p nil)
   (message-goto-body))

 (defun notmuch-mua-forward-message ()
diff --git a/test/emacs b/test/emacs
index ac47b16..aecbf41 100755
--- a/test/emacs
+++ b/test/emacs
@@ -268,7 +268,8 @@ Subject: Re: Testing message sent via SMTP
 In-Reply-To: 
 Fcc: $(pwd)/mail/sent
 --text follows this line--
-On 01 Jan 2000 12:00:00 -, Notmuch Test Suite  wrote:
+Notmuch Test Suite  writes:
+
 > This is a test that messages are sent via SMTP
 EOF
 test_expect_equal_file OUTPUT EXPECTED
-- 
1.7.5.4



[PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread Xavier Maillard
On Sun, 22 Jan 2012 10:35:47 +0200, Tomi Ollila  wrote:
> Like in emacs/*.el two comment chars (;;) is required so that
> (indent-region) doesn't break indentation.
> ---
>  .dir-locals.el |6 +++---

+1

/Xavier


[PATCH v4 2/3] emacs: `notmuch-show-buttonize-links' only `notmuch-show's a message if it exists

2012-01-22 Thread Mark Walters

> * emacs/notmuch-show.el (notmuch-show-if-found): new function that only shows
>   a message/thread if present in the database and otherwise returns an error.

I like this in principle but it interacts awkwardly with the automatic tag
exclusion. If the id: matches a message with an excluded tag
then notmuch-show-if-found will not let you view it, but if you typed the
same search in a search field it would show you the message. 

Note notmuch show currently does not currently respect excluded tags (see
id:"871uqvgrnm.fsf at qmul.ac.uk"), and this is not completely trivial to
fix since it is not clear quite what its behaviour should be in some
corner cases.

Perhaps we could have an option like "--include-all" to notmuch
search/count to tell it not to apply the exclusions. On the other hand
that might also be useful as something the user can type in a search box
so a special search term (eg include:all) might be better.

Best wishes

Mark




[PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread Tomi Ollila
Like in emacs/*.el two comment chars (;;) is required so that
(indent-region) doesn't break indentation.
---
 .dir-locals.el |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.dir-locals.el b/.dir-locals.el
index 044c214..fc75ae6 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,6 +1,6 @@
-; emacs local configuration settings for notmuch source
-; surmised by dkg on 2010-11-23 13:43:18-0500
-; amended by amdragon on 2011-06-06
+;; emacs local configuration settings for notmuch source
+;; surmised by dkg on 2010-11-23 13:43:18-0500
+;; amended by amdragon on 2011-06-06

 ((c-mode
   (indent-tabs-mode . t)
-- 
1.7.6.1



[PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread Pieter Praet
On Sun, 22 Jan 2012 10:35:47 +0200, Tomi Ollila  wrote:
> Like in emacs/*.el two comment chars (;;) is required so that
> (indent-region) doesn't break indentation.
> ---

+1


Peace

-- 
Pieter


[PATCH v4 3/3] emacs: colorize buttonized 'id:' links depending on the target message's state

2012-01-22 Thread Pieter Praet
* emacs/notmuch-show.el

  (notmuch-show-buttonized-link-colors):
- new defcustom, allows toggling colorization of buttonized links.

  (notmuch-show-buttonized-link-available),
  (notmuch-show-buttonized-link-available-and-unread),
  (notmuch-show-buttonized-link-missing):
- new faces for buttonized id: links.

  (notmuch-show-found-target-p):
- add optional arg SUBQUERY to allow addition filtering,
  eg. with "tag:unread".

  (notmuch-show-buttonize-links):
- tweak `Message-Id' regexp: less greedy matching.
- use different face property depending on the result of
  `notmuch-show-found-target-p', causing buttons to available,
  available-and-unread and missing messages to be displayed in
  different colors.
---

Updated regexp.

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

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 972ac79..c04fc28 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -899,6 +899,38 @@ current buffer, if possible."
 (defvar notmuch-show-buffer-name nil)
 (make-variable-buffer-local 'notmuch-show-buffer-name)

+(defcustom notmuch-show-buttonized-link-colors t
+  "Colorize buttonized links depending on their target's state.
+
+Also see `notmuch-show-buttonized-link-available',
+ `notmuch-show-buttonized-link-available-and-unread',
+ `notmuch-show-buttonized-link-missing'.
+
+Might impact performance."
+  :type 'boolean
+  :group 'notmuch-show)
+
+(defface notmuch-show-buttonized-link-available
+  '((t (:inherit goto-address-mail-face :foreground "blue")))
+  "Face used for buttonized links to messages which are present
+in the mail store."
+  :group 'notmuch-show
+  :group 'notmuch-faces)
+
+(defface notmuch-show-buttonized-link-available-and-unread
+  '((t (:inherit goto-address-mail-face :foreground "green")))
+  "Face used for buttonized links to messages which are present
+in the mail store, and are tagged `unread'."
+  :group 'notmuch-show
+  :group 'notmuch-faces)
+
+(defface notmuch-show-buttonized-link-missing
+  '((t (:inherit goto-address-mail-face :foreground "red")))
+  "Face used for buttonized links to messages which are NOT
+present in in the mail store."
+  :group 'notmuch-show
+  :group 'notmuch-faces)
+
 (defun notmuch-show-buttonize-links (start end)
   "Buttonize URLs and mail addresses between START and END.

@@ -907,7 +939,7 @@ a corresponding notmuch search."
   (goto-address-fontify-region start end)
   (save-excursion
 (goto-char start)
-(while (re-search-forward "id:\\(\"?\\)[^[:space:]\"]+\\1" end t)
+(while (re-search-forward 
"id:\\(\"?\\)[^[:space:]\"]+@[^[:space:]\"]\\{3,\\}\\1" end t)
   (let ((message-id (match-string-no-properties 0))
(string-start (match-beginning 0))
(string-end (match-end 0)))
@@ -918,7 +950,14 @@ a corresponding notmuch search."
 (notmuch-show-if-found ,message-id))
  'follow-link t
  'help-echo "Mouse-1, RET: search for this message"
- 'face goto-address-mail-face)
+ 'face (if notmuch-show-buttonized-link-colors
+   (cond
+((notmuch-show-found-target-p message-id 
"and tag:unread")
+ 
'notmuch-show-buttonized-link-available-and-unread)
+((notmuch-show-found-target-p message-id 
nil)
+ 'notmuch-show-buttonized-link-available)
+(t 'notmuch-show-buttonized-link-missing))
+ 'goto-address-mail-face))

 ;;;###autoload
 (defun notmuch-show (thread-id  parent-buffer query-context 
buffer-name crypto-switch)
@@ -1008,8 +1047,8 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
 (notmuch-kill-this-buffer)
 (notmuch-show-worker thread-id parent-buffer query-context buffer-name 
process-crypto)))

-(defun notmuch-show-found-target-p (target)
-  (let ((args `("count" ,target)))
+(defun notmuch-show-found-target-p (target  subquery)
+  (let ((args `("count" ,target ,(or subquery ""
 (> (string-to-number
(with-output-to-string
  (apply 'call-process notmuch-command nil standard-output nil args)))
-- 
1.7.8.1



[PATCH v4 2/3] emacs: `notmuch-show-buttonize-links' only `notmuch-show's a message if it exists

2012-01-22 Thread Pieter Praet
* emacs/notmuch-show.el (notmuch-show-found-target-p): new predicate function
  that uses notmuch(1) 'count' to see if a query turns up any results.

* emacs/notmuch-show.el (notmuch-show-if-found): new function that only shows
  a message/thread if present in the database and otherwise returns an error.

* emacs/notmuch-show.el (notmuch-show-buttonize-links): some deduplication,
  and use new function `notmuch-show-if-found' instead of `notmuch-show'
  to prevent showing a blank screen for Message-Id's which aren't present
  in the database.
---
 emacs/notmuch-show.el |   31 +++
 1 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 57dd232..972ac79 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -908,14 +908,17 @@ a corresponding notmuch search."
   (save-excursion
 (goto-char start)
 (while (re-search-forward "id:\\(\"?\\)[^[:space:]\"]+\\1" end t)
-  ;; remove the overlay created by goto-address-mode
-  (remove-overlays (match-beginning 0) (match-end 0) 'goto-address t)
-  (make-text-button (match-beginning 0) (match-end 0)
-   'action `(lambda (arg)
-  (notmuch-show ,(match-string-no-properties 
0)))
-   'follow-link t
-   'help-echo "Mouse-1, RET: search for this message"
-   'face goto-address-mail-face
+  (let ((message-id (match-string-no-properties 0))
+   (string-start (match-beginning 0))
+   (string-end (match-end 0)))
+   ;; remove the overlay created by goto-address-mode
+   (remove-overlays string-start string-end 'goto-address t)
+   (make-text-button string-start string-end
+ 'action `(lambda (arg)
+(notmuch-show-if-found ,message-id))
+ 'follow-link t
+ 'help-echo "Mouse-1, RET: search for this message"
+ 'face goto-address-mail-face)

 ;;;###autoload
 (defun notmuch-show (thread-id  parent-buffer query-context 
buffer-name crypto-switch)
@@ -1005,6 +1008,18 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
 (notmuch-kill-this-buffer)
 (notmuch-show-worker thread-id parent-buffer query-context buffer-name 
process-crypto)))

+(defun notmuch-show-found-target-p (target)
+  (let ((args `("count" ,target)))
+(> (string-to-number
+   (with-output-to-string
+ (apply 'call-process notmuch-command nil standard-output nil args)))
+   0)))
+
+(defun notmuch-show-if-found (target  args)
+  (if (notmuch-show-found-target-p target)
+  (notmuch-show target args)
+(error "Can't find target: %s" target)))
+
 (defvar notmuch-show-stash-map
   (let ((map (make-sparse-keymap)))
 (define-key map "c" 'notmuch-show-stash-cc)
-- 
1.7.8.1



[PATCH v4 1/3] emacs: s/buttonise/buttonize/g

2012-01-22 Thread Pieter Praet
"Worldwide, -ize endings prevail in scientific writing and are commonly
used by many international organizations, such as the ISO and the
WHO. The European Union switched from -ize to -ise some years ago in its
English language publications, and this resulted in the coexistence of
the -ize spelling in older legislative acts and the -ise spelling in
more recent ones." ... and other convincing reasons [1].

Let's follow the good example of academic and standards bodies,
instead of the errors of a non-democratic pseudo-authority [2].

[1] 
http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences#Greek-derived_spellings
[2] http://en.wikipedia.org/wiki/Democratic_deficit_in_the_European_Union
---
 emacs/notmuch-show.el |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index e6a5b31..57dd232 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -899,8 +899,8 @@ current buffer, if possible."
 (defvar notmuch-show-buffer-name nil)
 (make-variable-buffer-local 'notmuch-show-buffer-name)

-(defun notmuch-show-buttonise-links (start end)
-  "Buttonise URLs and mail addresses between START and END.
+(defun notmuch-show-buttonize-links (start end)
+  "Buttonize URLs and mail addresses between START and END.

 This also turns id:\"\"-parts into buttons for
 a corresponding notmuch search."
@@ -976,7 +976,7 @@ buffer."
  (notmuch-show-insert-forest
   (notmuch-query-get-threads basic-args

-  (jit-lock-register #'notmuch-show-buttonise-links)
+  (jit-lock-register #'notmuch-show-buttonize-links)

   (run-hooks 'notmuch-show-hook))

-- 
1.7.8.1



[PATCH] v2 emacs: colorize buttonized 'id:' links depending on the target message's state

2012-01-22 Thread Pieter Praet
On Fri, 20 Jan 2012 12:15:13 -0700, Mark Anderson  
wrote:
> On Wed, 18 Jan 2012 04:08:54 -0600, Pieter Praet  wrote:
> > On Mon, 16 Jan 2012 16:43:06 -0500, Aaron Ecay  
> > wrote:
> > > On Mon, 16 Jan 2012 17:57:33 +0100, Pieter Praet  
> > > wrote:
> > > [...] Maybe you could change the regex that
> > > matches id:?s to require a little more structure ? an at-sign, perhaps.
> > > Or even requiring more than (say) 5 non-space characters after the
> > > message id would cut down sharply on the false positive rate.
> > > 
> > 
> > Not sure how that would pan out.  It's fairly common behaviour to put
> > one or more spaces after a inline Message-Id, so I don't think such a
> > limitation would be warmly recepted.
> 
> I thought this was a suggestion to have more than 5 non-space characters
> after the id:, not the full id:LongIdThingHere 
> 

Now that you mention it...

I may have taken Aaron's suggestion a bit too literally. :)

> It sounded to me like an attempt to prevent extra false positives and
> the confusing buttonizing and notmuch queries that go with them.
> 
> -Mark
> 


Peace

-- 
Pieter


[PATCH] test: make (kill-emacs) from emacsclient work with emacs 23.(1|2)

2012-01-22 Thread David Bremner
On Fri, 13 Jan 2012 10:17:28 +0200, Tomi Ollila  wrote:
> emacsclient --eval '(kill-emacs)' makes emacs versions 23.1
> and 23.2 ask user input from running emacs. Redefining
> yes-or-no-p function when kill-emacs is executed for these
> emacs versions in test-lib.el avoids this test problem.

pushed,

d


[PATCH] test: whitespace-cleanup for most test/* files

2012-01-22 Thread David Bremner
On Wed, 11 Jan 2012 18:53:59 +0200, Tomi Ollila  wrote:
> Used emacs (whitespace-cleanup) function to "cleanup blank problems"
> in test files where that could be done without breaking tests;
> test/emacs was partially, and test/multipart was fully reverted.

pushed, 

d


[PATCH] show: don't use hex literals in JSON output

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 01:20:57 +0100, Thomas Jost  
wrote:
> JSON does not support hex literals (0x..) so numbers must be formatted
> as %d instead of %x.

pushed, 

d


[PATCH] Fix NEWS about gmime 2.6

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 01:29:41 +0100, Thomas Jost  
wrote:
> Previous version had a typo ("they may be" instead of "there may be")
> and was lacking a proper description of the gmime bug.
> ---

pushed, 

d


[PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 10:35:47 +0200, Tomi Ollila  wrote:
> Like in emacs/*.el two comment chars (;;) is required so that
> (indent-region) doesn't break indentation.

Pushed

d


heads up from the python front

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 06:01:41 -, Justus Winter <4winter at 
informatik.uni-hamburg.de> wrote:
> 
> I feel kind of bad since I severely broke the error handling for all
> pythonic notmuch users out there, is there any chance of a bugfix
> release? The patch[3] is really simple and I'd say it's trivial to
> backport it to the last release. What do you think?
> 

I'm not opposed in principle; I tentatively plan on a bugfix release for
Aaron's mml quoting patch, so we can have the two fixes in one release.
It would be good to get a bit more feedback on the patch itself. Can you
post a backported (to branch release) version of the patch to the list?

> 3: 8015cbff263606f009b5750d23b28ee332c25db8



[PATCH 4/4] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Pieter Praet
On Thu, 19 Jan 2012 23:19:02 -0500, Austin Clements  wrote:
> [...]
> Hah, okay.  How about this as an initial minor refactoring of the code
> for new.tags?
> [...]

Great, thanks!


Would the following commit message be satisfactory? :

  #+begin_quote
setup: move tag printing and parsing into separate functions

* notmuch-setup.c (notmuch_setup_command):
  Break tag printing and response parsing out into separate functions
  called `print_tag_list' respectively `parse_tag_list', for reuse
  with the 'search.exclude_tags' option.
  #+end_quote

(if not, please suggest an alternative; it'll be your name at the top)


Thanks again!


Peace

-- 
Pieter


[PATCH] test: whitespace-cleanup for most test/* files

2012-01-22 Thread Pieter Praet
On Wed, 11 Jan 2012 18:53:59 +0200, Tomi Ollila  wrote:
> Used emacs (whitespace-cleanup) function to "cleanup blank problems"
> in test files where that could be done without breaking tests;
> test/emacs was partially, and test/multipart was fully reverted.
> ---

+1


Peace

-- 
Pieter


[PATCH] emacs: Quote MML tags in replies

2012-01-22 Thread Pieter Praet
On Thu, 19 Jan 2012 22:26:02 -0500, Aaron Ecay  wrote:
> On Fri, 20 Jan 2012 00:21:08 +0100, Pieter Praet  wrote:
> > So, would I be right to assume MML tags in signatures are never
> > evaluated to begin with?  Otherwise, there would still be a security
> > hole, no?
> 
> I am thinking of MML tags that a user puts in their own signature.
> If that case is a security hole, then the hole is in the user?s brain
> and not in notmuch.  :)
> 

Ah, right...  I didn't bother checking what the mark's position would be,
so assumed we were talking about the signature in the *quoted* message.

Won't happen again :)

> -- 
> Aaron Ecay


Peace

-- 
Pieter


heads up from the python front

2012-01-22 Thread Justus Winter
Hey everyone :)

after getting to know nmbug a little better (it's actually very nice
to track bugs and patches this way...) I did some work on the python
bindings. tl;dr version: housekeeping, python3.2 support, fixed nasty
bug.

I familiarized myself with nmbug and went through all the threads
tagged with notmuch::python, added and updated few tags here and there
and started working on the open issues.

Python 3.2 support
--

I merged the last patch of a patchset[0] I wrote in december that makes
it possible to use the python bindings with both python2.x and
python3.2.

I do not now how complete the port is, most notably the notmuch.py
script does not work with 3.x. But it is complete enough to make
afew[1] work using python3.2 and the vanilla notmuch bindings.

If you want to help out and have a small script that uses the bindings
I'd like to invite you to try to port your script and report any
issues.

Fix random crashes when using the bindings
--

I found a nasty bug I introduced with a patchset[2] that was supposed
to make the bindings more robust. Annotating pointers returned from
libnotmuch functions called using ctypes allows the ctypes framework
to do typechecking. But I accidentally broke the error handling
code. Citing the commit message:

Before 3434d1940 the return values of libnotmuch functions were
declared as c_void_p and the code checking for errors compared the
returned value to None, which is the ctypes equivalent of a NULL
pointer.

But said commit wrapped all the data types in python classes and the
semantic changed in a subtle way. If a function returns NULL, the
wrapped python value is falsish, but no longer equal to None.

In fact the minimal test case triggering the bug is:

import os
import notmuch

db_path = os.path.expanduser('~/Maildir')

db_0 = notmuch.Database(db_path, mode=notmuch.Database.MODE.READ_WRITE)
db_1 = notmuch.Database(db_path, mode=notmuch.Database.MODE.READ_WRITE)

The problem was most apparent when opening the database fails because
it has been locked by someone else. The patch regarding the function
Database.open looks like this:

 res = Database._open(_str(path), mode)

-if res is None:
+if not res:
 raise NotmuchError(message="Could not open the specified database")
 self._db = res

The old code fails to notify the callee of the error who causes a
segfault later if he uses that database reference which is in fact
NULL.

I feel kind of bad since I severely broke the error handling for all
pythonic notmuch users out there, is there any chance of a bugfix
release? The patch[3] is really simple and I'd say it's trivial to
backport it to the last release. What do you think?

Justus

0: id:1323860305-15802-1-git-send-email-4winter at informatik.uni-hamburg.de
1: https://github.com/teythoon/afew
2: id:1318198374-926-1-git-send-email-4winter at informatik.uni-hamburg.de
3: 8015cbff263606f009b5750d23b28ee332c25db8


[PATCH v7 2/2] emacs: Tests for user-defined sections

2012-01-22 Thread Daniel Schoepe
From: Daniel Schoepe 

---
 test/emacs |   37 
 test/emacs.expected-output/notmuch-hello   |4 ++-
 .../notmuch-hello-new-section  |4 ++
 .../notmuch-hello-no-saved-searches|4 ++-
 .../notmuch-hello-section-counts   |5 +++
 .../notmuch-hello-section-hidden-tag   |4 ++
 .../notmuch-hello-section-with-empty   |4 ++
 .../emacs.expected-output/notmuch-hello-with-empty |4 ++-
 8 files changed, 63 insertions(+), 3 deletions(-)
 create mode 100644 test/emacs.expected-output/notmuch-hello-new-section
 create mode 100644 test/emacs.expected-output/notmuch-hello-section-counts
 create mode 100644 test/emacs.expected-output/notmuch-hello-section-hidden-tag
 create mode 100644 test/emacs.expected-output/notmuch-hello-section-with-empty

diff --git a/test/emacs b/test/emacs
index ac47b16..8b1d16c 100755
--- a/test/emacs
+++ b/test/emacs
@@ -29,6 +29,43 @@ test_emacs '(let ((notmuch-saved-searches
  (test-output))'
 test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-no-saved-searches

+test_begin_subtest "User defined section with inbox tag"
+test_emacs "(let ((notmuch-hello-sections 
+   (list (lambda () (notmuch-hello-insert-searches
+ \"Test\" '((\"inbox\" . 
\"tag:inbox\")))
+   (notmuch-hello)
+   (test-output))"
+test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-new-section
+
+test_begin_subtest "User defined section with empty, hidden entry"
+test_emacs "(let ((notmuch-hello-sections 
+   (list (lambda () (notmuch-hello-insert-searches
+ \"Test-with-empty\" 
+ '((\"inbox\" . \"tag:inbox\")
+   (\"doesnotexist\" . 
\"tag:doesnotexist\"))
+ :hide-empty-searches t)
+ (notmuch-hello)
+ (test-output))"
+test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-with-empty
+
+test_begin_subtest "User defined section, unread tag filtered out"
+test_emacs "(let ((notmuch-hello-sections 
+   (list (lambda () (notmuch-hello-insert-tags-section
+ \"Test-with-filtered\"
+ :hide-tags '(\"unread\"))
+ (notmuch-hello)
+ (test-output))"
+test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-hidden-tag
+
+test_begin_subtest "User defined section, different query for counts"
+test_emacs "(let ((notmuch-hello-sections
+   (list (lambda () (notmuch-hello-insert-tags-section
+ \"Test-with-counts\"
+ :filter-count \"tag:signed\")
+ (notmuch-hello)
+ (test-output))"
+test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-counts
+
 test_begin_subtest "Basic notmuch-search view in emacs"
 test_emacs '(notmuch-search "tag:inbox")
(notmuch-test-wait)
diff --git a/test/emacs.expected-output/notmuch-hello 
b/test/emacs.expected-output/notmuch-hello
index 196112e..cf49cb4 100644
--- a/test/emacs.expected-output/notmuch-hello
+++ b/test/emacs.expected-output/notmuch-hello
@@ -6,9 +6,11 @@ Saved searches: [edit]

 Search: .

-[Show all tags]
+All tags: [show]

 Type a search query and hit RET to view matching threads.
Edit saved searches with the `edit' button.
   Hit RET or click on a saved search or tag name to view matching threads.
 `=' refreshes this screen. `s' jumps to the search box. `q' to quit.
+   Customize this page.
+
diff --git a/test/emacs.expected-output/notmuch-hello-new-section 
b/test/emacs.expected-output/notmuch-hello-new-section
new file mode 100644
index 000..c64d712
--- /dev/null
+++ b/test/emacs.expected-output/notmuch-hello-new-section
@@ -0,0 +1,4 @@
+Test: [hide]
+
+ 52 inbox  
+
diff --git a/test/emacs.expected-output/notmuch-hello-no-saved-searches 
b/test/emacs.expected-output/notmuch-hello-no-saved-searches
index f4cfe49..cec0f91 100644
--- a/test/emacs.expected-output/notmuch-hello-no-saved-searches
+++ b/test/emacs.expected-output/notmuch-hello-no-saved-searches
@@ -2,9 +2,11 @@

 Search: .

-[Show all tags]
+All tags: [show]

 Type a search query and hit RET to view matching threads.
Edit saved searches with the `edit' button.
   Hit RET or click on a saved search or tag name to view matching threads.
 `=' refreshes this screen. `s' jumps to the search box. `q' to quit.
+   Customize this page.
+
diff --git 

[PATCH v7 1/2] emacs: User-defined sections in notmuch-hello

2012-01-22 Thread Daniel Schoepe
From: Daniel Schoepe 

This patch makes the notmuch-hello screen fully customizable
by allowing the user to add and remove arbitrary sections. It
also provides some convenience functions for constructing sections,
e.g. showing the unread message count for each tag.

This is done by specifying a list of functions that will be run
when notmuch-hello is invoked.
---
 emacs/notmuch-hello.el |  620 
 1 files changed, 420 insertions(+), 200 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 63f2e07..5ba9a11 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -159,6 +159,101 @@ International Bureau of Weights and Measures."

 (defvar notmuch-hello-recent-searches nil)

+(defvar notmuch-hello-custom-section-options
+  '((:filter (string :tag "Filter for each tag"))
+(:filter-count (string :tag "Different filter to generate message counts"))
+(:initially-hidden (const :tag "Hide this section on startup" t))
+(:show-empty-searches (const :tag "Show queries with no matching messages" 
t))
+(:hide-if-empty (const :tag "Hide this section if all queries are empty
+\(and not hidden by show-if-empty)" t)))
+  "Various customization-options for notmuch-hello-tags/query-section.")
+
+(define-widget 'notmuch-hello-tags-section 'lazy
+  "Customize-type for notmuch-hello tag-list sections."
+  :tag "Customized tag-list section (see docstring for details)"
+  :type
+  `(list :tag ""
+(const :tag "" notmuch-hello-insert-tags-section)
+(string :tag "Title for this section")
+(plist
+ :inline t
+ :options
+ ,(append notmuch-hello-custom-section-options
+  '((:hide-tags (repeat :tag "Tags that will be hidden"
+string)))
+
+(define-widget 'notmuch-hello-query-section 'lazy
+  "Customize-type for custom saved-search-like sections"
+  :tag "Customized queries section (see docstring for details)"
+  :type
+  `(list :tag ""
+(const :tag "" notmuch-hello-insert-query-list)
+(string :tag "Title for this section")
+(repeat :tag "Queries"
+(cons (string :tag "Name") (string :tag "Query")))
+(plist :inline t :options ,notmuch-hello-custom-section-options)))
+
+(defcustom notmuch-hello-sections
+  (list #'notmuch-hello-insert-header
+   #'notmuch-hello-insert-saved-searches
+   #'notmuch-hello-insert-search
+   #'notmuch-hello-insert-recent-searches
+   #'notmuch-hello-insert-alltags
+   #'notmuch-hello-insert-footer)
+  "Sections for notmuch-hello.
+
+The list contains functions which are used to construct sections in
+notmuch-hello buffer.  When notmuch-hello buffer is constructed,
+these functions are run in the order they appear in this list.  Each
+function produces a section simply by adding content to the current
+buffer.  A section should not end with an empty line, because a
+newline will be inserted after each section by `notmuch-hello'.
+
+Each function should take no arguments.  If the produced section
+includes `notmuch-hello-target' (i.e. cursor should be positioned
+inside this section), the function should return this element's
+position.
+Otherwise, it should return nil.
+
+For convenience an element can also be a list of the form (FUNC ARG1
+ARG2 .. ARGN) in which case FUNC will be applied to the rest of the
+list.
+
+A \"Customized tag-list section\" item in the customize-interface
+displays a list of all tags, optionally hiding some of them. It
+is also possible to filter the list of messages matching each tag
+by an additional filter query. Similarly, the count of messages
+displayed next to the buttons can be generated by applying a
+different filter to the tag query. These filters are also
+supported for \"Customized queries section\" items."
+  :group 'notmuch
+  :type
+  '(repeat
+(choice (function-item notmuch-hello-insert-header)
+   (function-item notmuch-hello-insert-saved-searches)
+   (function-item notmuch-hello-insert-search)
+   (function-item notmuch-hello-insert-recent-searches)
+   (function-item notmuch-hello-insert-alltags)
+   (function-item notmuch-hello-insert-footer)
+   (function-item notmuch-hello-insert-inbox)
+   notmuch-hello-tags-section
+   notmuch-hello-query-section
+   (function :tag "Custom section"
+
+(defvar notmuch-hello-target nil
+  "Button text at position of point before rebuilding the notmuch-buffer.
+
+This variable contains the text of the button, if any, the
+point was positioned at before the notmuch-hello buffer was
+rebuilt. This should never actually be globaly and is defined as a
+defvar only for documentation purposes and to avoid a compiler
+warning about it occurring as a free variable.")
+
+(defvar notmuch-hello-hidden-sections nil
+  "List of sections titles whose contents are 

[PATCH v6 1/2] emacs: User-defined sections in notmuch-hello

2012-01-22 Thread Daniel Schoepe
hin the columns instead of the rows.

> 
> - "Major mode for convenient notmuch navigation. This is your entry portal 
> into notmuch.
> +  "Major mode for convenient notmuch navigation. This is your entry portal 
> into notmuch.
> 
> Please revert.
> 
> - (interactive)
> - (kill-all-local-variables)
> - (use-local-map notmuch-hello-mode-map)
> - (setq major-mode 'notmuch-hello-mode
> -   mode-name "notmuch-hello")
> - ;;(setq buffer-read-only t)
> -)
> -
> +  (interactive)
> +  (kill-all-local-variables)
> +  (use-local-map notmuch-hello-mode-map)
> +  (setq major-mode 'notmuch-hello-mode
> + mode-name "notmuch-hello"))
> +
> 
> Please revert.  The commented out line may be removed in a separate patch.
> 
> `notmuch-hello-generate-tag-alist':
> 
> +  (list tag (notmuch-hello-filtered-query tag filter-query)
> 
> It should be (concat "tag:" tag) instead of tag.  Besides we already
> have it in the query variable, so just use it.
> 
> +(cons tag (notmuch-hello-filtered-query
> +   (concat "tag:" tag) filter-query))
> 
> Same as above: use the query variable.
> 
> `notmuch-hello-insert-saved-searches':
> 
> Looks like we do not need both `final-target-pos'.  Can we just return
> `found-target-pos'?
> 
> `notmuch-hello-insert-search':
> 
> +  (insert "\n"))
> 
> Should this be `widget-insert'?
> 
> Note that there are changes in master that need to be merged into
> `notmuch-hello-insert-search' during rebase.
> 
> `notmuch-hello-insert-searches':
> 
> if my above comments on `notmuch-hello-query-counts' are correct, the
> docstring should be fixed because `notmuch-hello-insert-searches' does
> not handle :filter and :filter-count options.  Would be nice to move
> this documentation somewhere instead of deleting it.

I moved it to notmuch-hello-insert-tags-section, which actually
does handle those option and is a high-level function that will
probably be used a lot more by users.

> 
> +   (searches (apply 'notmuch-hello-query-counts query-alist options)))
> 
> Why do we need `apply' here?

Because we want each item in `options' to be passed as an individual
argument. Note that apply is a bit peculiar about its last argument.

> `notmuch-hello-insert-tags-section':
> 
> +  "Insert a section displaying all tags and message counts for each.
> 
> Perhaps s/and message counts for each/with message counts/?
> 
> `notmuch-hello-insert-inbox':
> 
> Perhaps change docstring to something more consistent with other
> notmuch-hello-insert-* functions?  E.g.:
> 
>   Insert a section displaying saved search and inbox messages for each
>   tag.

Changed, thanks.

> 
> +   (notmuch-hello-generate-tag-alist))
> +  :filter "tag:inbox"))
> 
> If my above comments are correct, then :filter option should be given
> to `notmuch-hello-generate-tag-alist' instead of
> `notmuch-hello-insert-searches'.
> 
> `notmuch-hello-insert-alltags':
> 
> Missing dot at the end of docstring.
> 
> Perhaps s/and associated message counts/with message counts/?
> 
> `notmuch-hello':
> 
> -  ; Jump through a hoop to get this value from the deprecated variable
> -  ; name (`notmuch-folders') or from the default value.
> +     ; Jump through a hoop to get this value 
> from the deprecated variable
> + ; name (`notmuch-folders') or from the 
> default value.
> 
> Please revert.
> 
>(if (not notmuch-saved-searches)
> -(setq notmuch-saved-searches (notmuch-saved-searches)))
> +  (setq notmuch-saved-searches (notmuch-saved-searches)))
> 
> Please revert.
> 
> +(setq notmuch-hello-first-run nil)))
> 
> Please move this statement to the top level.  There is no need for it
> to be inside let.

Fixed.

I'll send my current version shortly, which does not yet include
Michal's performance improvement, because there probably still be a few
rough edges. The performance improvement could also be put in separate
patch so I don't have to keep rebasing this uncomfortably big patch for
much longer.

Thank you for your very detailed review.

Cheers,
Daniel
-- 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/20120122/51063e51/attachment-0001.pgp>


[PATCH] Fix NEWS about gmime 2.6

2012-01-22 Thread Thomas Jost
Previous version had a typo ("they may be" instead of "there may be")
and was lacking a proper description of the gmime bug.
---
Argh. Did not know how to tell it in proper English, ended with a huge
typo. Sorry about that, and thanks for noticing and fixing it :)

 NEWS |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index e78472c..2c2d9e9 100644
--- a/NEWS
+++ b/NEWS
@@ -42,8 +42,8 @@ Build fixes
 Compatibility with GMime 2.6

   It is now possible to build notmuch against both GMime 2.4 and 2.6.
-  However they may be some issues in PGP signature verification
-  because of a bug in current versions of GMime 2.6.
+  However, a bug in current GMime 2.6 causes notmuch not to report
+  signatures where the signer key is unavailable (GNOME bug 668085).

 Notmuch 0.11 (2012-01-13)
 =
-- 
1.7.8.4



[PATCH] show: don't use hex literals in JSON output

2012-01-22 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted
as %d instead of %x.

Currently, the possible values for the gmime error code are 1 (expired
signature), 2 (no public key), 4 (expired key) and 8 (revoked key).
The other possible value is 16 (unsupported algorithm) but obviously
it is much more rare. If this happens, the current code will add
'"errors": 10'. This is valid JSON (it looks like a decimal number)
but it is incorrect (should be 16, not 10).

Since this is just an issue in the JSON encoder, no changes are needed
on the Emacs side (or in other UIs using the JSON output).
---

 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 43ee211..7b40568 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -728,7 +728,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (", \"keyid\": %s", json_quote_str (ctx_quote, 
signer->keyid));
}
if (signer->errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (", \"errors\": %x", signer->errors);
+   printf (", \"errors\": %d", signer->errors);
}

printf ("}");
-- 
1.7.8.4



[PATCH] lib: Save filenames for files detected as "not an email file" in the database.

2012-01-22 Thread Jani Nikula
On Fri, 20 Jan 2012 17:00:27 -0500, Austin Clements  wrote:
> Later runs of "notmuch new" won't scan these files again and won't
> print warnings.
> 
> Various programs (Dovecot, in my case) store indexes and caches and
> such in the maildir.  Without this, notmuch persistently complains
> about such files.

Overall, sounds good and doing this automagically is nice. Superficially
the code looks sensible, but I didn't really dig into it. A few nasty
questions instead:

What happens if you delete a non-email file? Does the entry stay in the
database?

What happens if you replace a non-email file with an email file?

Does it matter what happens above?

These are corner cases, but what remains in TODO suggests that it would
be difficult to debug and figure out if the above ever did happen to
someone.


BR,
Jani.


> ---
> Every time I run notmuch new I get a slew of these warnings.  It was
> starting to get on my nerves, so I implemented the solution suggested
> by the TODO file.
> 
>  devel/TODO  |9 +++--
>  lib/database.cc |   41 +
>  test/new|   23 +++
>  3 files changed, 67 insertions(+), 6 deletions(-)
> 
> diff --git a/devel/TODO b/devel/TODO
> index 4dda6f4..b64a26e 100644
> --- a/devel/TODO
> +++ b/devel/TODO
> @@ -260,12 +260,9 @@ existing messages at the next database upgrade).
>  Add support for the user to specify custom headers to be indexed (and
>  re-index these for existing messages at the next database upgrade).
>  
> -Save filenames for files detected as "not an email file" in the
> -database. This would allow for two things: 1. Optimizing "notmuch new"
> -to not have to look at these files again (since they are potentially
> -large so the detection could be potentially slow). 2. A "notmuch
> -search" syntax could be added to allow the user to find these files,
> -(and perhaps delete them or move them away as appropriate).
> +Add a "notmuch search" syntax to allow uses to find files recorded as
> +non-emails in the database (and perhaps delete them or move them away
> +as appropriate).
>  
>  Fix filesystem/notmuch-new race condition by not updating database
>  mtime for a directory if it is the same as the current mtime.
> diff --git a/lib/database.cc b/lib/database.cc
> index 8103bd9..fd1ec6e 100644
> --- a/lib/database.cc
> +++ b/lib/database.cc
> @@ -1618,6 +1618,43 @@ _notmuch_database_link_message (notmuch_database_t 
> *notmuch,
>  return NOTMUCH_STATUS_SUCCESS;
>  }
>  
> +static notmuch_status_t
> +_notmuch_database_add_nonemail (notmuch_database_t *notmuch,
> + const char *filename)
> +{
> +notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
> +void *local = talloc_new (notmuch);
> +char *term, *direntry;
> +Xapian::docid id;
> +
> +if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
> + INTERNAL_ERROR ("Failure to ensure database is writable");
> +
> +Xapian::WritableDatabase *db =
> + static_cast  (notmuch->xapian_db);
> +
> +/* Create a document to record the non-email */
> +Xapian::Document nonemail;
> +term = talloc_asprintf (local, "%s%s", _find_prefix ("type"), 
> "nonemail");
> +nonemail.add_term (term, 0);
> +
> +status = _notmuch_database_filename_to_direntry (local, notmuch,
> +  filename, );
> +if (status)
> + goto DONE;
> +term = talloc_asprintf (local, "%s%s", _find_prefix ("file-direntry"),
> + direntry);
> +nonemail.add_term (term, 0);
> +
> +/* Add it to the database */
> +id = _notmuch_database_generate_doc_id (notmuch);
> +db->replace_document (id, nonemail);
> +
> +  DONE:
> +talloc_free (local);
> +return status;
> +}
> +
>  notmuch_status_t
>  notmuch_database_add_message (notmuch_database_t *notmuch,
> const char *filename,
> @@ -1673,6 +1710,10 @@ notmuch_database_add_message (notmuch_database_t 
> *notmuch,
>   (subject == NULL || *subject == '\0') &&
>   (to == NULL || *to == '\0'))
>   {
> + /* The file is not an email.  Record it so we don't
> +  * reconsider this file in the future, which prevents
> +  * potentially expensive scans and annoying warnings. */
> + _notmuch_database_add_nonemail (notmuch, filename);
>   ret = NOTMUCH_STATUS_FILE_NOT_EMAIL;
>   goto DONE;
>   }
> diff --git a/test/new b/test/new
> index 49f390d..346d453 100755
> --- a/test/new
> +++ b/test/new
> @@ -153,4 +153,27 @@ rm -rf "${MAIL_DIR}"/two
>  output=$(NOTMUCH_NEW)
>  test_expect_equal "$output" "No new mail. Removed 3 messages."
>  
> +
> +test_begin_subtest "Skips non-email"
> +PRE_COUNT=$(notmuch search '*' | wc -l)
> +echo "I am not an email" > "${MAIL_DIR}"/nonemail
> +output=$(NOTMUCH_NEW 2>&1 | sed -n '/^Note:/p;$p' | sed 's/\(file:\) .*/\1 
> XXX/')
> +test_expect_equal "$output" "Note: Ignoring 

[PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Mark Walters

On Fri, 20 Jan 2012 12:18:01 -0500, Austin Clements  wrote:
> 
> Oh dear.
> 
> Well, here's one idea.  Instead of doing a single thread query in
> show, do a thread query without the exclusions and then a message
> query with the exclusions.  Output all of the messages from the first
> query, but use the results of the second query to determine which
> messages are "matched".  The same could be accomplished in the library
> somewhat more efficiently, but it's not obvious to me what the API
> would be.

I have been thinking about this and one question is what should the sort
order be? If I understand it correctly notmuch sorts the threads
by the oldest/newest matching message, so the "correct" behaviour if no
message matches is unclear. Perhaps all threads with a matching
non-excluded message sorted by the matching-non-excluded message
followed by all threads that match only on excluded messages with sort
based on the matching excluded message?

Best wishes

Mark



[PATCH] rewriting notmuch-search for structured output to make other output formats easier

2012-01-22 Thread Peter Feigl
On Sat, 21 Jan 2012 15:12:57 -0800, Jameson Graef Rollins  wrote:
> On Sat, 21 Jan 2012 22:16:08 +0100, Peter Feigl  wrote:
> > The output routines have been rewritten so that logical structure
> > (objects with key/value pairs, arrays, strings and numbers) are
> > written instead of ad-hoc printfs. This allows for easier adaptation
> > of other output formats, as only the routines that start/end an object
> > etc. have to be rewritten. The logic is the same for all formats.
> > The default text output is handled differently, special cases are
> > inserted at the proper places, as it differs too much from the
> > structured output.
> 
> Hi, Peter.  Thanks for the contribution.
> 
> There are a lot of changes in this patch so I think you need to think
> about how you can break this up into multiple smaller and more atomic
> patches.  In particular, the addition of the sexp output format needs to
> definitely be in a separate patch from the restructuring of the output
> formatting.  You also don't mention anywhere in the commit log that
> you've added this new output format.  You'll also need to include
> documentation and test suite updates.

I'm sorry I forgot to mention that, it was mainly meant as a way to show
that this is easily possible (i.e. that the formatting is decoupled from
the logic, so that additional and different formats can be added without
influencing the printing logic). It'd be easy to split this up. What
kind of documentation should I include? 
The test suite should work fine, *if* it compares EXPECTED and OUTPUT
not character-by-character, but rather by pretty-printing both the
expected and the actual outputs by some JSON pretty-printer (like python
-mjson.tool). I can of course provide additional test-cases for
--format=sexp.

How should I proceed on this? Re-submit the patch with the sexp-support
removed and only JSON updated?

Thanks!

Peter


[PATCH] rewriting notmuch-search for structured output to make other output formats easier

2012-01-22 Thread Peter Feigl
On Sat, 21 Jan 2012 17:04:07 -0500, Austin Clements  wrote:
> Quoth Peter Feigl on Jan 21 at 10:16 pm:
> I think this is a great idea and I'm a fan of having an S-expression
> format, but I also think there's a much easier and more general way to
> structure this.
> 
> In particular, I don't think you should hijack search_format, since
> you'll wind up repeating most of this work for anything else that
> needs to output structured data (notmuch show, at least).  Rather, I'd
> suggest creating a general "structure printer" struct that isn't tied
> to search.  You've essentially already done this, you just called it
> search_format.  Then, leave the existing format callbacks in place,
> just use this new API instead of lots of printf calls.

I'm sorry I haven't been more clear about this, the intention was all
along to check whether this would be ok in notmuch-search, and if it got
accepted there, to factor it out into a separate file and then use it in
notmuch-show and notmuch-reply. There's nothing in the printer (except
for the name of the struct) that ties it to search.

> What about all of those annoying {tag,item}_{start,sep,end} fields?  I
> think you can simultaneously get rid of those *and* simplify the
> structure printer API.  If the structure printer is allowed to keep a
> little state, it can automatically insert separators.  With a little
> nesting state, it could even insert terminators by just saying "pop me
> to this level".  This could probably be better, but I'm imagining
> something like

I agree, however this is complicated by the fact that there are
additional restrictions on the actually printed code: newlines should be
placed at strategic locations to improve parsability, which could be
hard to decide in the printer alone without support from the logic that
drives it.

> struct sprinter *
> new_json_sprinter (const void *ctx, FILE *stream);
> struct sprinter *
> new_sexp_sprinter (const void *ctx, FILE *stream);
> 
> /* Start a map (a JSON object or a S-expression alist/plist/whatever)
>  * and return the nesting level of the map. */
> int
> sprinter_map (struct sprinter *sp);
> /* Start a list (aka array) and return the nesting level of the list. */
> int
> sprinter_list (struct sprinter *sp);
> 
> /* Close maps and lists until reaching level. */
> void
> sprinter_pop (struct sprinter *sp, int level);
> 
> void
> sprinter_map_key (struct sprinter *sp, const char *key);
> void
> sprinter_number (struct sprinter *sp, int val);
> void
> sprinter_string (struct sprinter *sp, const char *val);
> void
> sprinter_bool (struct sprinter *sp, notmuch_bool_t val);
> 
> and that's it.  This would also subsume your format_attribute_*
> helpers.
> 
> Unfortunately, it's a pain to pass things like a structure printer
> object around formatters (too bad notmuch isn't written in C++, eh?).
> I think it's better to address this than to structure around it.
> Probably the simplest thing to do is to make a struct for formatter
> state and pass that in to the callbacks.  You could also more
> completely emulate classes, but that would probably be overkill for
> this.

I believe this approach is similar to the one I've implemented (though
probably higher level, not so many details explicitly written into the
formatting code). I would suggest trying to get any sort of structured
formatters (whether more like your suggestions or like the thing I
implemented doesn't matter so much) into the main codebase, and then
refactoring the other parts to use it. I've thought about providing a
single patch to all of notmuch that accomplishes this, but I've deemed
it too large and complicated to be accepted, I thought limiting it to
notmuch-search would be a way to get it set up, so that it could be
expanded to the other parts later.

Thanks for the comments, I'll keep thinking about your design, a very
interesting idea!

Peter
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 274 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120122/7a526e63/attachment.pgp>


[PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread Tomi Ollila
Like in emacs/*.el two comment chars (;;) is required so that
(indent-region) doesn't break indentation.
---
 .dir-locals.el |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.dir-locals.el b/.dir-locals.el
index 044c214..fc75ae6 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,6 +1,6 @@
-; emacs local configuration settings for notmuch source
-; surmised by dkg on 2010-11-23 13:43:18-0500
-; amended by amdragon on 2011-06-06
+;; emacs local configuration settings for notmuch source
+;; surmised by dkg on 2010-11-23 13:43:18-0500
+;; amended by amdragon on 2011-06-06
 
 ((c-mode
   (indent-tabs-mode . t)
-- 
1.7.6.1

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


Re: [PATCH] v2 emacs: colorize buttonized 'id:' links depending on the target message's state

2012-01-22 Thread Pieter Praet
On Fri, 20 Jan 2012 12:15:13 -0700, Mark Anderson markr.ander...@amd.com 
wrote:
 On Wed, 18 Jan 2012 04:08:54 -0600, Pieter Praet pie...@praet.org wrote:
  On Mon, 16 Jan 2012 16:43:06 -0500, Aaron Ecay aarone...@gmail.com wrote:
   On Mon, 16 Jan 2012 17:57:33 +0100, Pieter Praet pie...@praet.org wrote:
   [...] Maybe you could change the regex that
   matches id:’s to require a little more structure – an at-sign, perhaps.
   Or even requiring more than (say) 5 non-space characters after the
   message id would cut down sharply on the false positive rate.
   
  
  Not sure how that would pan out.  It's fairly common behaviour to put
  one or more spaces after a inline Message-Id, so I don't think such a
  limitation would be warmly recepted.
 
 I thought this was a suggestion to have more than 5 non-space characters
 after the id:, not the full id:LongIdThingHere 
 

Now that you mention it...

I may have taken Aaron's suggestion a bit too literally. :)

 It sounded to me like an attempt to prevent extra false positives and
 the confusing buttonizing and notmuch queries that go with them.
 
 -Mark
 


Peace

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


[PATCH v4 3/3] emacs: colorize buttonized 'id:' links depending on the target message's state

2012-01-22 Thread Pieter Praet
* emacs/notmuch-show.el

  (notmuch-show-buttonized-link-colors):
- new defcustom, allows toggling colorization of buttonized links.

  (notmuch-show-buttonized-link-available),
  (notmuch-show-buttonized-link-available-and-unread),
  (notmuch-show-buttonized-link-missing):
- new faces for buttonized id: links.

  (notmuch-show-found-target-p):
- add optional arg SUBQUERY to allow addition filtering,
  eg. with tag:unread.

  (notmuch-show-buttonize-links):
- tweak `Message-Id' regexp: less greedy matching.
- use different face property depending on the result of
  `notmuch-show-found-target-p', causing buttons to available,
  available-and-unread and missing messages to be displayed in
  different colors.
---

Updated regexp.

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

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 972ac79..c04fc28 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -899,6 +899,38 @@ current buffer, if possible.
 (defvar notmuch-show-buffer-name nil)
 (make-variable-buffer-local 'notmuch-show-buffer-name)
 
+(defcustom notmuch-show-buttonized-link-colors t
+  Colorize buttonized links depending on their target's state.
+
+Also see `notmuch-show-buttonized-link-available',
+ `notmuch-show-buttonized-link-available-and-unread',
+ `notmuch-show-buttonized-link-missing'.
+
+Might impact performance.
+  :type 'boolean
+  :group 'notmuch-show)
+
+(defface notmuch-show-buttonized-link-available
+  '((t (:inherit goto-address-mail-face :foreground blue)))
+  Face used for buttonized links to messages which are present
+in the mail store.
+  :group 'notmuch-show
+  :group 'notmuch-faces)
+
+(defface notmuch-show-buttonized-link-available-and-unread
+  '((t (:inherit goto-address-mail-face :foreground green)))
+  Face used for buttonized links to messages which are present
+in the mail store, and are tagged `unread'.
+  :group 'notmuch-show
+  :group 'notmuch-faces)
+
+(defface notmuch-show-buttonized-link-missing
+  '((t (:inherit goto-address-mail-face :foreground red)))
+  Face used for buttonized links to messages which are NOT
+present in in the mail store.
+  :group 'notmuch-show
+  :group 'notmuch-faces)
+
 (defun notmuch-show-buttonize-links (start end)
   Buttonize URLs and mail addresses between START and END.
 
@@ -907,7 +939,7 @@ a corresponding notmuch search.
   (goto-address-fontify-region start end)
   (save-excursion
 (goto-char start)
-(while (re-search-forward id:\\(\?\\)[^[:space:]\]+\\1 end t)
+(while (re-search-forward 
id:\\(\?\\)[^[:space:]\]+@[^[:space:]\]\\{3,\\}\\1 end t)
   (let ((message-id (match-string-no-properties 0))
(string-start (match-beginning 0))
(string-end (match-end 0)))
@@ -918,7 +950,14 @@ a corresponding notmuch search.
 (notmuch-show-if-found ,message-id))
  'follow-link t
  'help-echo Mouse-1, RET: search for this message
- 'face goto-address-mail-face)
+ 'face (if notmuch-show-buttonized-link-colors
+   (cond
+((notmuch-show-found-target-p message-id 
and tag:unread)
+ 
'notmuch-show-buttonized-link-available-and-unread)
+((notmuch-show-found-target-p message-id 
nil)
+ 'notmuch-show-buttonized-link-available)
+(t 'notmuch-show-buttonized-link-missing))
+ 'goto-address-mail-face))
 
 ;;;###autoload
 (defun notmuch-show (thread-id optional parent-buffer query-context 
buffer-name crypto-switch)
@@ -1008,8 +1047,8 @@ thread id.  If a prefix is given, crypto processing is 
toggled.
 (notmuch-kill-this-buffer)
 (notmuch-show-worker thread-id parent-buffer query-context buffer-name 
process-crypto)))
 
-(defun notmuch-show-found-target-p (target)
-  (let ((args `(count ,target)))
+(defun notmuch-show-found-target-p (target optional subquery)
+  (let ((args `(count ,target ,(or subquery 
 ( (string-to-number
(with-output-to-string
  (apply 'call-process notmuch-command nil standard-output nil args)))
-- 
1.7.8.1

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


[PATCH v4 1/3] emacs: s/buttonise/buttonize/g

2012-01-22 Thread Pieter Praet
Worldwide, -ize endings prevail in scientific writing and are commonly
used by many international organizations, such as the ISO and the
WHO. The European Union switched from -ize to -ise some years ago in its
English language publications, and this resulted in the coexistence of
the -ize spelling in older legislative acts and the -ise spelling in
more recent ones. ... and other convincing reasons [1].

Let's follow the good example of academic and standards bodies,
instead of the errors of a non-democratic pseudo-authority [2].

[1] 
http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences#Greek-derived_spellings
[2] http://en.wikipedia.org/wiki/Democratic_deficit_in_the_European_Union
---
 emacs/notmuch-show.el |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index e6a5b31..57dd232 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -899,8 +899,8 @@ current buffer, if possible.
 (defvar notmuch-show-buffer-name nil)
 (make-variable-buffer-local 'notmuch-show-buffer-name)
 
-(defun notmuch-show-buttonise-links (start end)
-  Buttonise URLs and mail addresses between START and END.
+(defun notmuch-show-buttonize-links (start end)
+  Buttonize URLs and mail addresses between START and END.
 
 This also turns id:\message id\-parts into buttons for
 a corresponding notmuch search.
@@ -976,7 +976,7 @@ buffer.
  (notmuch-show-insert-forest
   (notmuch-query-get-threads basic-args
 
-  (jit-lock-register #'notmuch-show-buttonise-links)
+  (jit-lock-register #'notmuch-show-buttonize-links)
 
   (run-hooks 'notmuch-show-hook))
 
-- 
1.7.8.1

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


Re: [PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread Pieter Praet
On Sun, 22 Jan 2012 10:35:47 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
 Like in emacs/*.el two comment chars (;;) is required so that
 (indent-region) doesn't break indentation.
 ---

+1


Peace

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


Re: [PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread Xavier Maillard
On Sun, 22 Jan 2012 10:35:47 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
 Like in emacs/*.el two comment chars (;;) is required so that
 (indent-region) doesn't break indentation.
 ---
  .dir-locals.el |6 +++---

+1

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


Re: [PATCH v4 2/3] emacs: `notmuch-show-buttonize-links' only `notmuch-show's a message if it exists

2012-01-22 Thread Mark Walters

 * emacs/notmuch-show.el (notmuch-show-if-found): new function that only shows
   a message/thread if present in the database and otherwise returns an error.

I like this in principle but it interacts awkwardly with the automatic tag
exclusion. If the id:message-id matches a message with an excluded tag
then notmuch-show-if-found will not let you view it, but if you typed the
same search in a search field it would show you the message. 

Note notmuch show currently does not currently respect excluded tags (see
id:871uqvgrnm@qmul.ac.uk), and this is not completely trivial to
fix since it is not clear quite what its behaviour should be in some
corner cases.

Perhaps we could have an option like --include-all to notmuch
search/count to tell it not to apply the exclusions. On the other hand
that might also be useful as something the user can type in a search box
so a special search term (eg include:all) might be better.

Best wishes

Mark


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


ignore folders patch?

2012-01-22 Thread Fabio Zanini
Hi!

This is my first message to the list. In 2010 a patch was developed that
enabled notmuch new to ignore certain subdirectories of the mail folder:

http://notmuchmail.org/pipermail/notmuch/2010/003170.html

However, I cannot find any reference to it in the git history, and it
does not seem to have been implemented.

This feature seems to be relevant, what would you think of reviving it
and including it into the codebase? I could try to update the patch
myself.

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


Re: [PATCH] lib: Save filenames for files detected as not an email file in the database.

2012-01-22 Thread Jani Nikula
On Sat, 21 Jan 2012 18:49:19 -0500, Austin Clements amdra...@mit.edu wrote:
 Quoth Jani Nikula on Jan 22 at  1:00 am:
  On Fri, 20 Jan 2012 17:00:27 -0500, Austin Clements amdra...@mit.edu 
  wrote:
   Later runs of notmuch new won't scan these files again and won't
   print warnings.
   
   Various programs (Dovecot, in my case) store indexes and caches and
   such in the maildir.  Without this, notmuch persistently complains
   about such files.
  
  Overall, sounds good and doing this automagically is nice. Superficially
  the code looks sensible, but I didn't really dig into it. A few nasty
  questions instead:
  
  What happens if you delete a non-email file? Does the entry stay in the
  database?
 
 Phooey.  I thought this worked, but you're right that it doesn't (I
 even wrote a test for this, but the test was based on a false
 assumption).  Non-email files do get returned by the directory
 iterator, so without any changes, notmuch new will notice that they're
 gone.  What I missed is that it then uses
 notmuch_database_find_message_by_filename to find the message and
 remove the filename, which won't work since there's no message to
 find.
 
 I'll have to think about this more.

Sorry about that...

This feature has considerable overlap with file/subdirectory exclusion,
most recently referred to in id:20120122113212.GA7084@X200. I like the
way your approach is automatic, but doing it manually with configurable
exclusions has certain explicitness to it, and altogether avoids the
problems here, don't you think? There apparently also are people who
wouldn't want notmuch to index some valid email files for one reason or
another.

I haven't thought this through, but what if the exclude/ignore feature
had both the option to specify explicit files/subdirs (patterns like
.gitignore?) that are ignored, and some sort of auto option you could
enable to ignore all non-email files without warnings? This would
obviously all happen in the cli.

That probably does not make your thinking any easier, I'm afraid... but
perhaps it provides another angle.


BR,
Jani.


 
  What happens if you replace a non-email file with an email file?
 
 It will not notice because notmuch new only inspects directory mtimes.
 This would require checking the mtimes of every non-email in the
 database on every notmuch new.
 
  Does it matter what happens above?
  
  These are corner cases, but what remains in TODO suggests that it would
  be difficult to debug and figure out if the above ever did happen to
  someone.
 
 Yes.  It's possible this needs to get a search syntax before it is
 acceptable for general use.
 
  BR,
  Jani.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: heads up from the python front

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 06:01:41 -, Justus Winter 
4win...@informatik.uni-hamburg.de wrote:
 
 I feel kind of bad since I severely broke the error handling for all
 pythonic notmuch users out there, is there any chance of a bugfix
 release? The patch[3] is really simple and I'd say it's trivial to
 backport it to the last release. What do you think?
 

I'm not opposed in principle; I tentatively plan on a bugfix release for
Aaron's mml quoting patch, so we can have the two fixes in one release.
It would be good to get a bit more feedback on the patch itself. Can you
post a backported (to branch release) version of the patch to the list?

 3: 8015cbff263606f009b5750d23b28ee332c25db8

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


Re: [PATCH] .dir-locals.el: changed one-char comment prefix '; ' to two; '; ; '

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 10:35:47 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
 Like in emacs/*.el two comment chars (;;) is required so that
 (indent-region) doesn't break indentation.

Pushed

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


Re: [PATCH] Fix NEWS about gmime 2.6

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 01:29:41 +0100, Thomas Jost schno...@schnouki.net wrote:
 Previous version had a typo (they may be instead of there may be)
 and was lacking a proper description of the gmime bug.
 ---

pushed, 

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


Re: [PATCH] show: don't use hex literals in JSON output

2012-01-22 Thread David Bremner
On Sun, 22 Jan 2012 01:20:57 +0100, Thomas Jost schno...@schnouki.net wrote:
 JSON does not support hex literals (0x..) so numbers must be formatted
 as %d instead of %x.

pushed, 

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


[PATCH] python: fix error handling

2012-01-22 Thread Justus Winter
Before 3434d1940 the return values of libnotmuch functions were
declared as c_void_p and the code checking for errors compared the
returned value to None, which is the ctypes equivalent of a NULL
pointer.

But said commit wrapped all the data types in python classes and the
semantic changed in a subtle way. If a function returns NULL, the
wrapped python value is falsish, but no longer equal to None.

Backported from master to 0.11.
---
 bindings/python/notmuch/database.py |   16 
 bindings/python/notmuch/filename.py |2 +-
 bindings/python/notmuch/message.py  |6 +++---
 bindings/python/notmuch/tag.py  |2 +-
 bindings/python/notmuch/thread.py   |6 +++---
 5 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/bindings/python/notmuch/database.py 
b/bindings/python/notmuch/database.py
index 7923f76..0074ba3 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -168,7 +168,7 @@ class Database(object):
 
 res = Database._create(_str(path), Database.MODE.READ_WRITE)
 
-if res is None:
+if not res:
 raise NotmuchError(
 message=Could not create the specified database)
 self._db = res
@@ -188,7 +188,7 @@ class Database(object):
 
 res = Database._open(_str(path), mode)
 
-if res is None:
+if not res:
 raise NotmuchError(message=Could not open the specified database)
 self._db = res
 
@@ -645,7 +645,7 @@ class Query(object):
 self._db = db
 # create query, return None if too little mem available
 query_p = Query._create(db.db_p, _str(querystr))
-if query_p is None:
+if not query_p:
 raise NullPointerError
 self._query = query_p
 
@@ -679,7 +679,7 @@ class Query(object):
 self._assert_query_is_initialized()
 threads_p = Query._search_threads(self._query)
 
-if threads_p is None:
+if not threads_p:
 raise NullPointerError
 return Threads(threads_p, self)
 
@@ -693,7 +693,7 @@ class Query(object):
 self._assert_query_is_initialized()
 msgs_p = Query._search_messages(self._query)
 
-if msgs_p is None:
+if not msgs_p:
 raise NullPointerError
 return Messages(msgs_p, self)
 
@@ -759,7 +759,7 @@ class Directory(object):
 def _assert_dir_is_initialized(self):
 Raises a NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
 if dir_p is None
-if self._dir_p is None:
+if not self._dir_p:
 raise NotmuchError(STATUS.NOT_INITIALIZED)
 
 def __init__(self, path, dir_p, parent):
@@ -920,7 +920,7 @@ class Filenames(object):
 _move_to_next.restype = None
 
 def next(self):
-if self._files_p is None:
+if not self._files_p:
 raise NotmuchError(STATUS.NOT_INITIALIZED)
 
 if not self._valid(self._files_p):
@@ -946,7 +946,7 @@ class Filenames(object):
  # NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
  for file in files: print file
 
-if self._files_p is None:
+if not self._files_p:
 raise NotmuchError(STATUS.NOT_INITIALIZED)
 
 i = 0
diff --git a/bindings/python/notmuch/filename.py 
b/bindings/python/notmuch/filename.py
index a7cd7e6..f7313ec 100644
--- a/bindings/python/notmuch/filename.py
+++ b/bindings/python/notmuch/filename.py
@@ -69,7 +69,7 @@ class Filenames(object):
  reference to it, so we can automatically delete the db object
  once all derived objects are dead.
 
-if files_p is None:
+if not files_p:
 raise NotmuchError(STATUS.NULL_POINTER)
 
 self._files = files_p
diff --git a/bindings/python/notmuch/message.py 
b/bindings/python/notmuch/message.py
index ce8e718..5540df3 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -116,7 +116,7 @@ class Messages(object):
 :TODO: Make the iterator work more than once and cache the tags in
the Python object.(?)
 
-if msgs_p is None:
+if not msgs_p:
 raise NotmuchError(STATUS.NULL_POINTER)
 
 self._msgs = msgs_p
@@ -321,7 +321,7 @@ class Message(object):
   automatically delete the parent object once all derived
   objects are dead.
 
-if msg_p is None:
+if not msg_p:
 raise NotmuchError(STATUS.NULL_POINTER)
 self._msg = msg_p
 #keep reference to parent, so we keep it alive
@@ -380,7 +380,7 @@ class Message(object):
 
 msgs_p = Message._get_replies(self._msg)
 
-if msgs_p is None:
+if not msgs_p:
 return None
 
 return Messages(msgs_p, self)
diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py
index 2fb7d32..4881db9 100644
--- 

Re: [PATCH] test: whitespace-cleanup for most test/* files

2012-01-22 Thread David Bremner
On Wed, 11 Jan 2012 18:53:59 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
 Used emacs (whitespace-cleanup) function to cleanup blank problems
 in test files where that could be done without breaking tests;
 test/emacs was partially, and test/multipart was fully reverted.

pushed, 

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


Re: [PATCH] test: make (kill-emacs) from emacsclient work with emacs 23.(1|2)

2012-01-22 Thread David Bremner
On Fri, 13 Jan 2012 10:17:28 +0200, Tomi Ollila tomi.oll...@iki.fi wrote:
 emacsclient --eval '(kill-emacs)' makes emacs versions 23.1
 and 23.2 ask user input from running emacs. Redefining
 yes-or-no-p function when kill-emacs is executed for these
 emacs versions in test-lib.el avoids this test problem.

pushed,

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


Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Austin Clements
Quoth Pieter Praet on Jan 22 at  7:55 am:
 On Thu, 19 Jan 2012 23:19:02 -0500, Austin Clements amdra...@mit.edu wrote:
  [...]
  Hah, okay.  How about this as an initial minor refactoring of the code
  for new.tags?
  [...]
 
 Great, thanks!
 
 
 Would the following commit message be satisfactory? :
 
   #+begin_quote
 setup: move tag printing and parsing into separate functions
 
 * notmuch-setup.c (notmuch_setup_command):
   Break tag printing and response parsing out into separate functions
   called `print_tag_list' respectively `parse_tag_list', for reuse
   with the 'search.exclude_tags' option.
   #+end_quote
 
 (if not, please suggest an alternative; it'll be your name at the top)

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


Re: [PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Austin Clements
Quoth Mark Walters on Jan 22 at 12:38 am:
 
 On Fri, 20 Jan 2012 12:18:01 -0500, Austin Clements amdra...@mit.edu wrote:
  
  Oh dear.
  
  Well, here's one idea.  Instead of doing a single thread query in
  show, do a thread query without the exclusions and then a message
  query with the exclusions.  Output all of the messages from the first
  query, but use the results of the second query to determine which
  messages are matched.  The same could be accomplished in the library
  somewhat more efficiently, but it's not obvious to me what the API
  would be.
 
 I have been thinking about this and one question is what should the sort
 order be? If I understand it correctly notmuch sorts the threads
 by the oldest/newest matching message, so the correct behaviour if no
 message matches is unclear. Perhaps all threads with a matching
 non-excluded message sorted by the matching-non-excluded message
 followed by all threads that match only on excluded messages with sort
 based on the matching excluded message?

I don't think show sorts in any particular way.  Or are you saying
that search also needs to know the difference between excluded and
non-excluded matched messages?
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Austin Clements
Quoth myself on Jan 20 at 12:18 pm:
 Quoth Mark Walters on Jan 20 at 12:10 am:
  
  Ok Having said this is trivial I have found a problem. What should
  notmuch do if you do something like
  
  notmuch show id:some-id
  and that message is marked with a deleted tag? To be consistent with the
  other cases (where a deleted message is in a matched thread) we might
  want to return the message with the not-matched flag set (eg in
  JSON). But my patch doesn't, as it never even sees the thread since it
  doesn't match.
  
  Looking at notmuch-show.c I think we should not apply the exclude tags
  to do_show_single, but usually should apply it to do_show. One solution
  which is simple and is at least close to right would be to get do_show
  to return the number of threads found. If this is zero then retry the
  query without the excludes (possible setting the match_flag to zero on
  each message since we know it does not match)
  
  This is not a completely correct solution as if you ask notmuch-show to
  show more than one thread it might  threads which only contain deleted
  messages.
  
  I can't see other good possibilities without slowing down the normal
  path a lot (eg find all threads that match the original query and then
  apply the argument above).
  
  Any thoughts?
 
 Oh dear.
 
 Well, here's one idea.  Instead of doing a single thread query in
 show, do a thread query without the exclusions and then a message
 query with the exclusions.  Output all of the messages from the first
 query, but use the results of the second query to determine which
 messages are matched.  The same could be accomplished in the library
 somewhat more efficiently, but it's not obvious to me what the API
 would be.

Here's a slightly crazier idea that's more library-invasive than the
original approach, but probably better in the long run.

Have notmuch_query_search_* return everything and make exclusion a
message flag like NOTMUCH_MESSAGE_FLAG_MATCH.  Tweak the definition of
matched to mean matched and not excluded (specifically, a message
would have the match flag or the excluded flag or neither, but not
both).  Search would skip threads with zero matched messages and I
think show would Just Work.

I can think of two ways to implement this.  notmuch_query_search_*
could perform both the original query and the query with exclusions
and use the docid set from the second to compute the excluded
message flag.  Alternatively, it could examine the tags of each
message directly to compute the flag.  The latter is probably easier
to implement, but probably slower.

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


Re: [PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Mark Walters

On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements amdra...@mit.edu wrote:
 Quoth myself on Jan 20 at 12:18 pm:
  Quoth Mark Walters on Jan 20 at 12:10 am:
   
   Ok Having said this is trivial I have found a problem. What should
   notmuch do if you do something like
   
   notmuch show id:some-id
   and that message is marked with a deleted tag? To be consistent with the
   other cases (where a deleted message is in a matched thread) we might
   want to return the message with the not-matched flag set (eg in
   JSON). But my patch doesn't, as it never even sees the thread since it
   doesn't match.
   
   Looking at notmuch-show.c I think we should not apply the exclude tags
   to do_show_single, but usually should apply it to do_show. One solution
   which is simple and is at least close to right would be to get do_show
   to return the number of threads found. If this is zero then retry the
   query without the excludes (possible setting the match_flag to zero on
   each message since we know it does not match)
   
   This is not a completely correct solution as if you ask notmuch-show to
   show more than one thread it might  threads which only contain deleted
   messages.
   
   I can't see other good possibilities without slowing down the normal
   path a lot (eg find all threads that match the original query and then
   apply the argument above).
   
   Any thoughts?
  
  Oh dear.
  
  Well, here's one idea.  Instead of doing a single thread query in
  show, do a thread query without the exclusions and then a message
  query with the exclusions.  Output all of the messages from the first
  query, but use the results of the second query to determine which
  messages are matched.  The same could be accomplished in the library
  somewhat more efficiently, but it's not obvious to me what the API
  would be.
 
 Here's a slightly crazier idea that's more library-invasive than the
 original approach, but probably better in the long run.
 
 Have notmuch_query_search_* return everything and make exclusion a
 message flag like NOTMUCH_MESSAGE_FLAG_MATCH.  Tweak the definition of
 matched to mean matched and not excluded (specifically, a message
 would have the match flag or the excluded flag or neither, but not
 both).  Search would skip threads with zero matched messages and I
 think show would Just Work.
 
 I can think of two ways to implement this.  notmuch_query_search_*
 could perform both the original query and the query with exclusions
 and use the docid set from the second to compute the excluded
 message flag.  Alternatively, it could examine the tags of each
 message directly to compute the flag.  The latter is probably easier
 to implement, but probably slower.

I really like the idea of returning two flags. I think your first
suggestion works better for sorting reasons: we want to return a thread
which has a match-not-excluded message and also a match-excluded message
to be sorted based on the match-not-excluded message. Hence in
notmuch_query_search_threads we can create the list of docids to iterate
over as the list generated by query with exclusions followed by the list
without exclusions.  This list contains lots of messages twice but that
doesn't matter since we have to check whether we have already output
the message in an earlier thread anyway. 

Incidentally, it might not take very much more code to allow
notmuch_query_search_threads to take two arbitrary queries and return
all threads which match the first case but mark as matched those that
match the second: i.e. a step on the way towards thread based and.

Best wishes

Mark


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


[PATCH v3 5/5] emacs: Use message-cite-original in reply

2012-01-22 Thread Adam Wolfe Gordon
Use message-mode's message-cite-original function to create the
quoted body for reply messages. In order to make this act like the
existing notmuch defaults, you will need to set the following in
your emacs configuration:

message-citation-line-format On %a, %d %b %Y, %f wrote:
message-citation-line-function 'message-insert-formatted-citation-line

The test has been updated to reflect the (ugly) emacs default.
---

Here is an alternate version of the patch, which uses message-cite-original.

I suggest people try out this version and see if the behavior is
acceptable with some configuration tweaks. If it is, then we can
work on implementing the notmuch-emacs config file idea, and go
with this version. As I mentioned, the one thing I haven't figured
out how to do with configuration is make message-cite-original fill
the quoted message. This would probably be a dealbreaker for me, but
I suspect it can be done somehow with the right combination of hooks.

 emacs/notmuch-mua.el |   32 +++-
 test/emacs   |3 ++-
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 5ae0ccf..45c314d 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -21,6 +21,7 @@
 
 (require 'json)
 (require 'message)
+(require 'format-spec)
 
 (require 'notmuch-lib)
 (require 'notmuch-address)
@@ -134,19 +135,24 @@ list.
  (forward-line -1)
(goto-char (point-max)))
 
-  (insert (format On %s, %s wrote:\n
- (cdr (assq 'date original-headers))
- (cdr (assq 'from original-headers
-
-  (if plain-parts
- (mapc (lambda (part) (notmuch-mua-insert-part-quoted part)) 
plain-parts)
-   (mapc (lambda (part)
-   (notmuch-mua-insert-part-quoted (notmuch-mua-parse-html-part 
part)))
- html-parts))
-
-  (push-mark))
-(set-buffer-modified-p nil))
-
+  (let ((from (cdr (assq 'from original-headers)))
+   (date (cdr (assq 'date original-headers)))
+   (start (point)))
+
+   (insert From:  from \n)
+   (insert Date:  date \n\n)
+  
+   (if plain-parts
+   (mapc 'insert plain-parts)
+ (mapc (lambda (part)
+ (insert (notmuch-mua-parse-html-part part)))
+   html-parts))
+   (push-mark)
+   (goto-char start)
+   (message-cite-original
+
+  (push-mark)
+  (set-buffer-modified-p nil)
   (message-goto-body))
 
 (defun notmuch-mua-forward-message ()
diff --git a/test/emacs b/test/emacs
index ac47b16..aecbf41 100755
--- a/test/emacs
+++ b/test/emacs
@@ -268,7 +268,8 @@ Subject: Re: Testing message sent via SMTP
 In-Reply-To: XXX
 Fcc: $(pwd)/mail/sent
 --text follows this line--
-On 01 Jan 2000 12:00:00 -, Notmuch Test Suite test_su...@notmuchmail.org 
wrote:
+Notmuch Test Suite test_su...@notmuchmail.org writes:
+
  This is a test that messages are sent via SMTP
 EOF
 test_expect_equal_file OUTPUT EXPECTED
-- 
1.7.5.4

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


Re: [PATCH 2/3] emacs: Don't return the button from `notmuch-show-insert-part-header'.

2012-01-22 Thread Jameson Graef Rollins
On Fri, 20 Jan 2012 09:43:31 +, David Edmondson d...@dme.org wrote:
 Instead, allow the caller to specify some parameters for the
 button. Rework `notmuch-show-insert-part-multipart/signed' and
 `notmuch-show-insert-part-multipart/encrypted' accordingly, moving
 most of the code into a common
 `notmuch-show-insert-part-multipart/signed-or-encrypted' to reduce
 duplication.

Hi, David.  A couple of issues with this patch:

This patch seems to include multiple distinct changes.  There is a
change to notmuch-show-insert-part-header, but a seemingly unrelated
change to the insertion of signed/encrypted part buttons.  They should
be in separate patches.

I'm also not sure I understand why the proposed changes to the
signed/encrypted button insertion functions are necessary or desired.
Was there a problem with the logic as it was?  What is gained by having
one function filled with special casing to handle two things, rather
than having two distinct functions?

Finally, this patch throws out all the changes from the previous patch,
making the previous patch superfluous.

jamie.


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


Re: [PATCH v3 2/2] search: Support automatic tag exclusions

2012-01-22 Thread Xavier Maillard
Hey Pieter,

On Thu, 19 Jan 2012 20:19:00 +0100, Pieter Praet pie...@praet.org wrote:
 Nice feature!  I won't be using it myself, but I can imagine it being
 *very* useful for those who still feel the need to delete email :).

Adding a 'deleted' tag does not mean there will be a delete/purge
process ;) (currently I got 5k messages with the tag deleted ;). 

 Nitpicking:
 

[ ... ]

   So I'd like to suggest replacing all occurences of auto_exclude_tags
   with search_exclude_tags (and simply exclude_tags in the args to
   `_config_get_list' and `_config_set_list', of course).

+1
 
   Unfortunately, this would also partially invalidate your recent NEWS
   submission [2].
 
 - If the 'search.exclude_tags' option is missing from the config file,
   its value is automatically set to deleted;spam;, which probably isn't
   a sane default.  Luckily, you've already provided the solution [3].

I am against doing something /unsafe/ in the user's back. If there is no
option set intentionnaly by the user, there is nothing notmuch should
do -i.e no exclusion -

 - To make new users aware of the config option's existence, we should
   prompt them to configure it during setup.

+1

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


Re: [PATCH 3/4] config: only set search.exclude_tags to deleted; spam; during setup

2012-01-22 Thread Xavier Maillard

On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet pie...@praet.org wrote:
 If the 'search.exclude_tags' option is missing from the config file,
 its value is automatically set to deleted;spam;.  Taking PoLS/DWIM
 into account, this should probably only happen during setup.
 
 This patch is actually Austin Clements' work:
   id:20120117203211.gq16...@mit.edu

I do not think this is a sane default. As I told it in another post. I
do not expect notmuch to skew my search queries not that I specifically
asked.

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


Re: [PATCH 0/3] Second step of 'show' rewrite

2012-01-22 Thread Jameson Graef Rollins
On Wed, 18 Jan 2012 15:28:24 -0500, Austin Clements amdra...@mit.edu wrote:
 This adds support for self-recursive message formatters, while
 maintaining backwards compatibility with old style formatters.  After
 this, each format can be converted to the new style individually and,
 once they're all converted, a bunch of code can be deleted.
 
 These three patches are independent and can be pushed in any order.  I
 put them in a series because pushing them before any formatter
 rewrites will simplify dependencies between the individual formatter
 rewrites.

Hey, Austin.  I just looked through these patches and tested them out
and they look good.  Jani's comments are more incisive than anything I
could come up with.  +1 on the series, and I'm looking forward to the
next phase.

jamie.


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


Re: [PATCH 3/4] config: only set search.exclude_tags to deleted; spam; during setup

2012-01-22 Thread Jameson Graef Rollins
On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard xav...@maillard.im wrote:
 
 On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet pie...@praet.org wrote:
  If the 'search.exclude_tags' option is missing from the config file,
  its value is automatically set to deleted;spam;.  Taking PoLS/DWIM
  into account, this should probably only happen during setup.
  
  This patch is actually Austin Clements' work:
id:20120117203211.gq16...@mit.edu
 
 I do not think this is a sane default. As I told it in another post. I
 do not expect notmuch to skew my search queries not that I specifically
 asked.

Hi, Xavier.  Do you currently mark things as deleted or spam?  If
not, this would have no affect on your search results.  If you do, do
you currently expect those messages to show up in searches?  If so, why
did you mark them as deleted or spam to begin with?

I agree with your point in principle (ie. I don't generally want my
searches tampered with behind the scenes) but the issue here is about
messages that have been explicitly tagged as a form of trash.  Trash
is by it's nature something you're trying to get rid of.  If you wanted
to find something in the future, why would you put it in the trash in
the first place?

jamie.


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


Re: ignore folders patch?

2012-01-22 Thread Dirk-Jan C . Binnema

Hi,

On 2012-01-22T13:32:12 EET, Fabio Zanini wrote:

  Hi!
 
  This is my first message to the list. In 2010 a patch was developed that
  enabled notmuch new to ignore certain subdirectories of the mail folder:
 
  http://notmuchmail.org/pipermail/notmuch/2010/003170.html
 
  However, I cannot find any reference to it in the git history, and it
  does not seem to have been implemented.
 
  This feature seems to be relevant, what would you think of reviving it
  and including it into the codebase? I could try to update the patch
  myself.

I don't think my patch made it either:
 http://notmuchmail.org/pipermail/notmuch/2010/001103.html

which support ignoring directories by dropping a '.noindex' file in them. I've
been happily using that with the mu program for years.

Best wishes,
Dirk.

--
Dirk-Jan C. Binnema  Helsinki, Finland
e:d...@djcbsoftware.nl   w:www.djcbsoftware.nl
pgp: D09C E664 897D 7D39 5047 A178 E96A C7A1 017D DA3C
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 1/3] mime node: Record depth-first part numbers

2012-01-22 Thread Austin Clements
Quoth myself on Jan 18 at  9:12 pm:
 Quoth Jani Nikula on Jan 19 at 12:25 am:
  FWIW, I'm not a big fan of casting away const. Either it is const, or it
  isn't. Not very many places would be affected if you dropped the const
  qualifier from the related interface(s) altogether, and things would
  look cleaner here. But I suppose this is a matter of taste.
 
 I'm not particularly happy with this either.  Unfortunately, dropping
 the const here affects a surprising number of places, including the
 entire MIME node API.

I've changed my mind and removed a few consts so that this funny cast
isn't necessary.  (It also turned out that when I tried this before,
I'd given up just a smidgen before removing enough consts to make it
work.)

 I think that, at a deep level, depth-first numbering simply doesn't
 resonate with an extremely hierarchical API like this and that
 dissonance is going to have to focus somewhere.  There have been
 discussions of switching to hierarchical part numbering before (in
 particular, because depth-first numbering is unstable with encrypted
 parts) and I'll probably restart those after all of this is done.

I have not, however, changed my mind about this.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Mark Walters
On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements amdra...@mit.edu wrote:
 Quoth myself on Jan 20 at 12:18 pm:
  Quoth Mark Walters on Jan 20 at 12:10 am:
   
   Ok Having said this is trivial I have found a problem. What should
   notmuch do if you do something like
   
   notmuch show id:some-id
   and that message is marked with a deleted tag? To be consistent with the
   other cases (where a deleted message is in a matched thread) we might
   want to return the message with the not-matched flag set (eg in
   JSON). But my patch doesn't, as it never even sees the thread since it
   doesn't match.
   
   Looking at notmuch-show.c I think we should not apply the exclude tags
   to do_show_single, but usually should apply it to do_show. One solution
   which is simple and is at least close to right would be to get do_show
   to return the number of threads found. If this is zero then retry the
   query without the excludes (possible setting the match_flag to zero on
   each message since we know it does not match)
   
   This is not a completely correct solution as if you ask notmuch-show to
   show more than one thread it might  threads which only contain deleted
   messages.
   
   I can't see other good possibilities without slowing down the normal
   path a lot (eg find all threads that match the original query and then
   apply the argument above).
   
   Any thoughts?
  
  Oh dear.
  
  Well, here's one idea.  Instead of doing a single thread query in
  show, do a thread query without the exclusions and then a message
  query with the exclusions.  Output all of the messages from the first
  query, but use the results of the second query to determine which
  messages are matched.  The same could be accomplished in the library
  somewhat more efficiently, but it's not obvious to me what the API
  would be.
 
 Here's a slightly crazier idea that's more library-invasive than the
 original approach, but probably better in the long run.
 
 Have notmuch_query_search_* return everything and make exclusion a
 message flag like NOTMUCH_MESSAGE_FLAG_MATCH.  Tweak the definition of
 matched to mean matched and not excluded (specifically, a message
 would have the match flag or the excluded flag or neither, but not
 both).  Search would skip threads with zero matched messages and I
 think show would Just Work.
 
 I can think of two ways to implement this.  notmuch_query_search_*
 could perform both the original query and the query with exclusions
 and use the docid set from the second to compute the excluded
 message flag.  Alternatively, it could examine the tags of each
 message directly to compute the flag.  The latter is probably easier
 to implement, but probably slower.
 
 Thoughts?

I have now thought about this some more and think I understand your idea
(and how it would work) rather better now. 

I would suggest one small change: the flags for the messages returned
should be independent: so a message can match the query or not, and it
can be excluded or not, with all 4 combinations being possible. (The
consumer of notmuch_query_search_* would extract the information it
wanted.)

I have thought about some implementation ideas but I think sorting is
going to be the deciding factor: what order should
notmuch_query_search_* return messages/threads? 

For notmuch_query_search_messages either it returns them all together
with the excluded messages marked, or returns all included ones, and
then all excluded one.

For notmuch_query_search_threads it is less clear. Currently it returns
threads in order of first matching message. It is not clear what
matching means now: is matching and included, or just matching? If the
former then we will be returning some threads with no matching and
included messages so we need to decide where to put them in the order.

If we sort in both cases just on matching then we have the same
output/sort as notmuch pre-excluded flags, just the frontends
notmuch-search/show can decide to omit some lines/results. Note that
after omitting excluded lines the thread sort would be different from
the current notmuch-with-excluded implementation.

Whereas if we sort based on matching and included, we keep the current
sort order with some stuff appended.

As regards implementation I think notmuch_query_search_messages is the
crucial place: once that returns one of its two orders the rest sort of
takes care of itself.

Best wishes

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


Re: [PATCH] Automatically exclude tags in notmuch-show

2012-01-22 Thread Austin Clements
Quoth Mark Walters on Jan 23 at  1:13 am:
 On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements amdra...@mit.edu wrote:
  Quoth myself on Jan 20 at 12:18 pm:
   Quoth Mark Walters on Jan 20 at 12:10 am:

Ok Having said this is trivial I have found a problem. What should
notmuch do if you do something like

notmuch show id:some-id
and that message is marked with a deleted tag? To be consistent with the
other cases (where a deleted message is in a matched thread) we might
want to return the message with the not-matched flag set (eg in
JSON). But my patch doesn't, as it never even sees the thread since it
doesn't match.

Looking at notmuch-show.c I think we should not apply the exclude tags
to do_show_single, but usually should apply it to do_show. One solution
which is simple and is at least close to right would be to get do_show
to return the number of threads found. If this is zero then retry the
query without the excludes (possible setting the match_flag to zero on
each message since we know it does not match)

This is not a completely correct solution as if you ask notmuch-show to
show more than one thread it might  threads which only contain deleted
messages.

I can't see other good possibilities without slowing down the normal
path a lot (eg find all threads that match the original query and then
apply the argument above).

Any thoughts?
   
   Oh dear.
   
   Well, here's one idea.  Instead of doing a single thread query in
   show, do a thread query without the exclusions and then a message
   query with the exclusions.  Output all of the messages from the first
   query, but use the results of the second query to determine which
   messages are matched.  The same could be accomplished in the library
   somewhat more efficiently, but it's not obvious to me what the API
   would be.
  
  Here's a slightly crazier idea that's more library-invasive than the
  original approach, but probably better in the long run.
  
  Have notmuch_query_search_* return everything and make exclusion a
  message flag like NOTMUCH_MESSAGE_FLAG_MATCH.  Tweak the definition of
  matched to mean matched and not excluded (specifically, a message
  would have the match flag or the excluded flag or neither, but not
  both).  Search would skip threads with zero matched messages and I
  think show would Just Work.
  
  I can think of two ways to implement this.  notmuch_query_search_*
  could perform both the original query and the query with exclusions
  and use the docid set from the second to compute the excluded
  message flag.  Alternatively, it could examine the tags of each
  message directly to compute the flag.  The latter is probably easier
  to implement, but probably slower.
  
  Thoughts?
 
 I have now thought about this some more and think I understand your idea
 (and how it would work) rather better now. 
 
 I would suggest one small change: the flags for the messages returned
 should be independent: so a message can match the query or not, and it
 can be excluded or not, with all 4 combinations being possible. (The
 consumer of notmuch_query_search_* would extract the information it
 wanted.)

I'd initially approached it this way, but went with redefining a
matched messages because it had much less impact on the API.  For
example, with the redefined match,
notmuch_thread_get_matched_messages still does the right thing for
search and things like the thread subject can still be based on
matched messages.  If we orthongonalize these flags, then we at
least need to count matched non-excluded messages and provide an API
to access this (while I don't have a solid argument against such an
API it just seems weirdly specific to me).

My other concern is performance.  In thread queries, marking
non-matched messages as excluded would require either an extra query
per thread or a single query to match all excluded messages (not
filtered by the primary query).  The former is prohibitive, though the
latter might be acceptable (that might depend on how many things
people mark as spam or deleted).  If the cost is too high, this
suggests that we shouldn't mark non-matched messages as excluded, but
then we're back to effectively having three levels of matching: not
matched, matched but not excluded, and matched but excluded.

 I have thought about some implementation ideas but I think sorting is
 going to be the deciding factor: what order should
 notmuch_query_search_* return messages/threads? 

Yes.  This is exactly what I've been puzzling over, too.

 For notmuch_query_search_messages either it returns them all together
 with the excluded messages marked, or returns all included ones, and
 then all excluded one.

I would prefer them intermingled.  I feel like returning one and then
the other is just exposing implementation details.  Plus, it's unclear
if the order of the two groups should depend on the sort order, be

[PATCH v2 0/3] Second step of 'show' rewrite

2012-01-22 Thread Austin Clements
This revision addresses Jani's comments.  It removes some
const-stripping casts (at the cost of dropping a const from the API),
fixes a delayed free, and cleans up some aesthetics.

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


[PATCH v2 1/3] mime node: Record depth-first part numbers

2012-01-22 Thread Austin Clements
This makes the part numbers readily accessible to formatters.
Hierarchical part numbering would be a more natural and efficient fit
for MIME and may be the way to go in the future, but depth-first
numbering maintains compatibility with what we currently do.
---
 mime-node.c  |   37 ++---
 notmuch-client.h |   14 +-
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index 27077f7..025c537 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -112,6 +112,10 @@ mime_node_open (const void *ctx, notmuch_message_t 
*message,
 root-nchildren = 1;
 root-ctx = mctx;
 
+root-part_num = 0;
+root-next_child = 0;
+root-next_part_num = 1;
+
 *root_out = root;
 return NOTMUCH_STATUS_SUCCESS;
 
@@ -137,7 +141,7 @@ _signature_validity_free (GMimeSignatureValidity **proxy)
 #endif
 
 static mime_node_t *
-_mime_node_create (const mime_node_t *parent, GMimeObject *part)
+_mime_node_create (mime_node_t *parent, GMimeObject *part)
 {
 mime_node_t *node = talloc_zero (parent, mime_node_t);
 GError *err = NULL;
@@ -150,6 +154,8 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
talloc_free (node);
return NULL;
 }
+node-parent = parent;
+node-part_num = node-next_part_num = -1;
 
 /* Deal with the different types of parts */
 if (GMIME_IS_PART (part)) {
@@ -267,9 +273,10 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 }
 
 mime_node_t *
-mime_node_child (const mime_node_t *parent, int child)
+mime_node_child (mime_node_t *parent, int child)
 {
 GMimeObject *sub;
+mime_node_t *node;
 
 if (!parent || child  0 || child = parent-nchildren)
return NULL;
@@ -287,7 +294,31 @@ mime_node_child (const mime_node_t *parent, int child)
INTERNAL_ERROR (Unexpected GMimeObject type: %s,
g_type_name (G_OBJECT_TYPE (parent-part)));
 }
-return _mime_node_create (parent, sub);
+node = _mime_node_create (parent, sub);
+
+if (child == parent-next_child  parent-next_part_num != -1) {
+   /* We're traversing in depth-first order.  Record the child's
+* depth-first numbering. */
+   node-part_num = parent-next_part_num;
+   node-next_part_num = node-part_num + 1;
+
+   /* Drop the const qualifier because these are internal fields
+* whose mutability doesn't affect the interface. */
+   parent-next_child++;
+   parent-next_part_num = -1;
+
+   if (node-nchildren == 0) {
+   /* We've reached a leaf, so find the parent that has more
+* children and set it up to number its next child. */
+   mime_node_t *it = node;
+   while (it  it-next_child == it-nchildren)
+   it = it-parent;
+   if (it)
+   it-next_part_num = node-part_num + 1;
+   }
+}
+
+return node;
 }
 
 static mime_node_t *
diff --git a/notmuch-client.h b/notmuch-client.h
index 9c1d383..abfe5d3 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -297,6 +297,13 @@ typedef struct mime_node {
 /* The number of children of this part. */
 int nchildren;
 
+/* The parent of this node or NULL if this is the root node. */
+struct mime_node *parent;
+
+/* The depth-first part number of this child if the MIME tree is
+ * being traversed in depth-first order, or -1 otherwise. */
+int part_num;
+
 /* True if decryption of this part was attempted. */
 notmuch_bool_t decrypt_attempted;
 /* True if decryption of this part's child succeeded.  In this
@@ -324,6 +331,11 @@ typedef struct mime_node {
 /* Internal: For successfully decrypted multipart parts, the
  * decrypted part to substitute for the second child. */
 GMimeObject *decrypted_child;
+
+/* Internal: The next child for depth-first traversal and the part
+ * number to assign it (or -1 if unknown). */
+int next_child;
+int next_part_num;
 } mime_node_t;
 
 /* Construct a new MIME node pointing to the root message part of
@@ -356,7 +368,7 @@ mime_node_open (const void *ctx, notmuch_message_t *message,
  * an error message on stderr).
  */
 mime_node_t *
-mime_node_child (const mime_node_t *parent, int child);
+mime_node_child (mime_node_t *parent, int child);
 
 /* Return the nth child of node in a depth-first traversal.  If n is
  * 0, returns node itself.  Returns NULL if there is no such part. */
-- 
1.7.7.3

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


[PATCH v2 3/3] show: Introduce mime_node formatter callback

2012-01-22 Thread Austin Clements
This callback is the gateway to the new mime_node_t-based formatters.
This maintains backwards compatibility so the formatters can be
transitioned one at a time.  Once all formatters are converted, the
formatter structure can be reduced to only message_set_{start,sep,end}
and part, most of show_message can be deleted, and all of
show-message.c can be deleted.
---
 notmuch-client.h |6 ++
 notmuch-reply.c  |2 +-
 notmuch-show.c   |   23 +++
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index abfe5d3..59606b4 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -62,8 +62,14 @@
 #define STRINGIFY(s) STRINGIFY_(s)
 #define STRINGIFY_(s) #s
 
+struct mime_node;
+struct notmuch_show_params;
+
 typedef struct notmuch_show_format {
 const char *message_set_start;
+void (*part) (const void *ctx,
+ struct mime_node *node, int indent,
+ struct notmuch_show_params *params);
 const char *message_start;
 void (*message) (const void *ctx,
 notmuch_message_t *message,
diff --git a/notmuch-reply.c b/notmuch-reply.c
index bf67960..f55b1d2 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -31,7 +31,7 @@ static void
 reply_part_content (GMimeObject *part);
 
 static const notmuch_show_format_t format_reply = {
-,
+, NULL,
, NULL,
, NULL, reply_headers_message_part, \n,
,
diff --git a/notmuch-show.c b/notmuch-show.c
index 682aa71..8185b02 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -42,7 +42,7 @@ static void
 format_part_end_text (GMimeObject *part);
 
 static const notmuch_show_format_t format_text = {
-,
+, NULL,
\fmessage{ , format_message_text,
\fheader{\n, format_headers_text, 
format_headers_message_part_text, \fheader}\n,
\fbody{\n,
@@ -89,7 +89,7 @@ static void
 format_part_end_json (GMimeObject *part);
 
 static const notmuch_show_format_t format_json = {
-[,
+[, NULL,
{, format_message_json,
\headers\: {, format_headers_json, 
format_headers_message_part_json, },
, \body\: [,
@@ -110,7 +110,7 @@ format_message_mbox (const void *ctx,
 unused (int indent));
 
 static const notmuch_show_format_t format_mbox = {
-,
+, NULL,
 , format_message_mbox,
 , NULL, NULL, ,
 ,
@@ -129,7 +129,7 @@ static void
 format_part_content_raw (GMimeObject *part);
 
 static const notmuch_show_format_t format_raw = {
-,
+, NULL,
, NULL,
, NULL, format_headers_message_part_text, \n,
 ,
@@ -850,6 +850,21 @@ show_message (void *ctx,
  int indent,
  notmuch_show_params_t *params)
 {
+if (format-part) {
+   void *local = talloc_new (ctx);
+   mime_node_t *root, *part;
+
+   if (mime_node_open (local, message, params-cryptoctx, params-decrypt,
+   root) != NOTMUCH_STATUS_SUCCESS)
+   goto DONE;
+   part = mime_node_seek_dfs (root, params-part  0 ? 0 : params-part);
+   if (part)
+   format-part (local, part, indent, params);
+  DONE:
+   talloc_free (local);
+   return;
+}
+
 if (params-part = 0) {
fputs (format-message_start, stdout);
if (format-message)
-- 
1.7.7.3

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


[PATCH v2 2/3] show: Use consistent header ordering in the text format

2012-01-22 Thread Austin Clements
Previously, top-level message headers were printed as Subject, From,
To, Date, while embedded message headers were printed From, To,
Subject, Date.  This makes both cases use the former order and updates
the tests accordingly.

Strangely, the raw format also uses this function, so this also fixes
the two raw format tests affected by this change.
---
 notmuch-show.c |2 +-
 test/multipart |   12 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 7b40568..682aa71 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -364,6 +364,7 @@ format_headers_message_part_text (GMimeMessage *message)
 InternetAddressList *recipients;
 const char *recipients_string;
 
+printf (Subject: %s\n, g_mime_message_get_subject (message));
 printf (From: %s\n, g_mime_message_get_sender (message));
 recipients = g_mime_message_get_recipients (message, 
GMIME_RECIPIENT_TYPE_TO);
 recipients_string = internet_address_list_to_string (recipients, 0);
@@ -375,7 +376,6 @@ format_headers_message_part_text (GMimeMessage *message)
 if (recipients_string)
printf (Cc: %s\n,
recipients_string);
-printf (Subject: %s\n, g_mime_message_get_subject (message));
 printf (Date: %s\n, g_mime_message_get_date_as_string (message));
 }
 
diff --git a/test/multipart b/test/multipart
index f83526b..2dd73f5 100755
--- a/test/multipart
+++ b/test/multipart
@@ -121,9 +121,9 @@ Date: Fri, 05 Jan 2001 15:43:57 +
 part{ ID: 2, Content-type: multipart/mixed
 part{ ID: 3, Content-type: message/rfc822
 header{
+Subject: html message
 From: Carl Worth cwo...@cworth.org
 To: cwo...@cworth.org
-Subject: html message
 Date: Fri, 05 Jan 2001 15:42:57 +
 header}
 body{
@@ -162,9 +162,9 @@ cat EOF EXPECTED
 part{ ID: 2, Content-type: multipart/mixed
 part{ ID: 3, Content-type: message/rfc822
 header{
+Subject: html message
 From: Carl Worth cwo...@cworth.org
 To: cwo...@cworth.org
-Subject: html message
 Date: Fri, 05 Jan 2001 15:42:57 +
 header}
 body{
@@ -200,9 +200,9 @@ cat EOF EXPECTED
 part{ ID: 2, Content-type: multipart/mixed
 part{ ID: 3, Content-type: message/rfc822
 header{
+Subject: html message
 From: Carl Worth cwo...@cworth.org
 To: cwo...@cworth.org
-Subject: html message
 Date: Fri, 05 Jan 2001 15:42:57 +
 header}
 body{
@@ -233,9 +233,9 @@ notmuch show --format=text --part=3 
'id:87liy5ap00@yoom.home.cworth.org' OU
 cat EOF EXPECTED
 part{ ID: 3, Content-type: message/rfc822
 header{
+Subject: html message
 From: Carl Worth cwo...@cworth.org
 To: cwo...@cworth.org
-Subject: html message
 Date: Fri, 05 Jan 2001 15:42:57 +
 header}
 body{
@@ -452,9 +452,9 @@ notmuch show --format=raw --part=1 
'id:87liy5ap00@yoom.home.cworth.org' OUT
 # output should *not* include newline
 echo OUTPUT
 cat EOF EXPECTED
+Subject: html message
 From: Carl Worth cwo...@cworth.org
 To: cwo...@cworth.org
-Subject: html message
 Date: Fri, 05 Jan 2001 15:42:57 +
 
 pThis is an embedded message, with a multipart/alternative part./p
@@ -476,9 +476,9 @@ test_expect_equal_file OUTPUT EXPECTED
 test_begin_subtest --format=raw --part=2, multipart/mixed
 notmuch show --format=raw --part=2 'id:87liy5ap00@yoom.home.cworth.org' 
OUTPUT
 cat EOF EXPECTED
+Subject: html message
 From: Carl Worth cwo...@cworth.org
 To: cwo...@cworth.org
-Subject: html message
 Date: Fri, 05 Jan 2001 15:42:57 +
 
 pThis is an embedded message, with a multipart/alternative part./p
-- 
1.7.7.3

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


Re: [PATCH v3 2/2] search: Support automatic tag exclusions

2012-01-22 Thread Pieter Praet
On Sun, 22 Jan 2012 23:09:30 +0100, Xavier Maillard xav...@maillard.im wrote:
 Hey Pieter,
 

Hi!

 On Thu, 19 Jan 2012 20:19:00 +0100, Pieter Praet pie...@praet.org wrote:
  Nice feature!  I won't be using it myself, but I can imagine it being
  *very* useful for those who still feel the need to delete email :).
 
 Adding a 'deleted' tag does not mean there will be a delete/purge
 process ;) (currently I got 5k messages with the tag deleted ;). 
 

Very true, that's why I put quotes around delete.

Deleting email for real is *so* old-fashioned... :D ;)

  Nitpicking:
  
 
 [ ... ]
 
So I'd like to suggest replacing all occurences of auto_exclude_tags
with search_exclude_tags (and simply exclude_tags in the args to
`_config_get_list' and `_config_set_list', of course).
 
 +1
  
Unfortunately, this would also partially invalidate your recent NEWS
submission [2].
  
  - If the 'search.exclude_tags' option is missing from the config file,
its value is automatically set to deleted;spam;, which probably isn't
a sane default.  Luckily, you've already provided the solution [3].
 
 I am against doing something /unsafe/ in the user's back. If there is no
 option set intentionnaly by the user, there is nothing notmuch should
 do -i.e no exclusion -
 

Absolutely.  Actually, that's *exactly* what I meant.

I thought that would be pretty clear, but perhaps it wasn't.
I've reworded some of the commit messages, and will pay more
attention to it in the future.

  - To make new users aware of the config option's existence, we should
prompt them to configure it during setup.
 
 +1
 
 /Xavier

Thanks for your input!


Peace

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


Re: [PATCH 3/4] config: only set search.exclude_tags to deleted; spam; during setup

2012-01-22 Thread Pieter Praet
On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard xav...@maillard.im wrote:
 
 On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet pie...@praet.org wrote:
  If the 'search.exclude_tags' option is missing from the config file,
  its value is automatically set to deleted;spam;.  Taking PoLS/DWIM
  into account, this should probably only happen during setup.
  
  This patch is actually Austin Clements' work:
id:20120117203211.gq16...@mit.edu
 
 I do not think this is a sane default. As I told it in another post. I
 do not expect notmuch to skew my search queries not that I specifically
 asked.
 

I agree 100%.  I've responded in more detail @ your previous reply:

  id:87ty3nawbt@praet.org

 /Xavier


Peace

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


Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Pieter Praet
On Sun, 22 Jan 2012 12:08:15 -0500, Austin Clements amdra...@mit.edu wrote:
 Quoth Pieter Praet on Jan 22 at  7:55 am:
  On Thu, 19 Jan 2012 23:19:02 -0500, Austin Clements amdra...@mit.edu 
  wrote:
   [...]
   Hah, okay.  How about this as an initial minor refactoring of the code
   for new.tags?
   [...]
  
  Great, thanks!
  
  
  Would the following commit message be satisfactory? :
  
#+begin_quote
  setup: move tag printing and parsing into separate functions
  
  * notmuch-setup.c (notmuch_setup_command):
Break tag printing and response parsing out into separate functions
called `print_tag_list' respectively `parse_tag_list', for reuse
with the 'search.exclude_tags' option.
#+end_quote
  
  (if not, please suggest an alternative; it'll be your name at the top)
 
 Sure.

Great!

Updated patch series follows.


Peace

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


[PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags

2012-01-22 Thread Pieter Praet
All other config-related functions and args include the section
title in their name, so for the sake of consistency, mirror that.

Also, the automatic part is a given, so that was dropped.
---
 notmuch-client.h |4 ++--
 notmuch-config.c |   28 ++--
 notmuch-count.c  |   12 ++--
 notmuch-search.c |   12 ++--
 4 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index 9c1d383..f5414f6 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -252,10 +252,10 @@ notmuch_config_set_maildir_synchronize_flags 
(notmuch_config_t *config,
  notmuch_bool_t synchronize_flags);
 
 const char **
-notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t 
*length);
+notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t 
*length);
 
 void
-notmuch_config_set_auto_exclude_tags (notmuch_config_t *config,
+notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
  const char *list[],
  size_t length);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index 8dcfe86..39da888 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -89,7 +89,7 @@ static const char search_config_comment[] =
 \n
  The following option is supported here:\n
 \n
-\tauto_exclude_tags\n
+\texclude_tags\n
 \t\tA ;-separated list of tags that will be excluded from\n
 \t\tsearch results by default.  Using an excluded tag in a\n
 \t\tquery will override that exclusion.\n;
@@ -106,8 +106,8 @@ struct _notmuch_config {
 const char **new_tags;
 size_t new_tags_length;
 notmuch_bool_t maildir_synchronize_flags;
-const char **auto_exclude_tags;
-size_t auto_exclude_tags_length;
+const char **search_exclude_tags;
+size_t search_exclude_tags_length;
 };
 
 static int
@@ -265,8 +265,8 @@ notmuch_config_open (void *ctx,
 config-new_tags = NULL;
 config-new_tags_length = 0;
 config-maildir_synchronize_flags = TRUE;
-config-auto_exclude_tags = NULL;
-config-auto_exclude_tags_length = 0;
+config-search_exclude_tags = NULL;
+config-search_exclude_tags_length = 0;
 
 if (! g_key_file_load_from_file (config-key_file,
 config-filename,
@@ -361,9 +361,9 @@ notmuch_config_open (void *ctx,
notmuch_config_set_new_tags (config, tags, 2);
 }
 
-if (notmuch_config_get_auto_exclude_tags (config, tmp) == NULL) {
+if (notmuch_config_get_search_exclude_tags (config, tmp) == NULL) {
const char *tags[] = { deleted, spam };
-   notmuch_config_set_auto_exclude_tags (config, tags, 2);
+   notmuch_config_set_search_exclude_tags (config, tags, 2);
 }
 
 error = NULL;
@@ -624,20 +624,20 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
 }
 
 const char **
-notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length)
+notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t 
*length)
 {
-return _config_get_list (config, search, auto_exclude_tags,
-(config-auto_exclude_tags),
-(config-auto_exclude_tags_length), length);
+return _config_get_list (config, search, exclude_tags,
+(config-search_exclude_tags),
+(config-search_exclude_tags_length), length);
 }
 
 void
-notmuch_config_set_auto_exclude_tags (notmuch_config_t *config,
+notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
  const char *list[],
  size_t length)
 {
-_config_set_list (config, search, auto_exclude_tags, list, length,
- (config-auto_exclude_tags));
+_config_set_list (config, search, exclude_tags, list, length,
+ (config-search_exclude_tags));
 }
 
 /* Given a configuration item of the form group.key return the
diff --git a/notmuch-count.c b/notmuch-count.c
index f77861e..63459fb 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -35,8 +35,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 char *query_str;
 int opt_index;
 int output = OUTPUT_MESSAGES;
-const char **auto_exclude_tags;
-size_t auto_exclude_tags_length;
+const char **search_exclude_tags;
+size_t search_exclude_tags_length;
 unsigned int i;
 
 notmuch_opt_desc_t options[] = {
@@ -78,10 +78,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
return 1;
 }
 
-auto_exclude_tags = notmuch_config_get_auto_exclude_tags
-   (config, auto_exclude_tags_length);
-for (i = 0; i  auto_exclude_tags_length; i++)
-   notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]);
+search_exclude_tags = notmuch_config_get_search_exclude_tags
+   (config, 

[PATCH v2 2/6] test: only exclude deleted messages from search if explicitly configured

2012-01-22 Thread Pieter Praet
Currently, the 'search.exclude_tags' option is automatically set to
deleted;spam; if it's missing from the config file.

This violates the Principle of Least Surprise, so update the tests to
*only* expect the exclusion of messages which are tagged deleted if the
'search.exclude_tags' option is explicitly set *and* contains that tag.
---
 test/search |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/test/search b/test/search
index bf965e7..99d94bd 100755
--- a/test/search
+++ b/test/search
@@ -130,6 +130,7 @@ output=$(notmuch search bödý | notmuch_search_sanitize)
 test_expect_equal $output thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; 
utf8-message-body-subject (inbox unread)
 
 test_begin_subtest Exclude \deleted\ messages from search
+notmuch config set search.exclude_tags = deleted
 generate_message '[subject]=Not deleted'
 generate_message '[subject]=Deleted'
 notmuch new  /dev/null
@@ -147,4 +148,11 @@ output=$(notmuch search subject:deleted | 
notmuch_search_sanitize)
 test_expect_equal $output thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; 
Not deleted (inbox unread)
 thread:XXX   2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted 
inbox unread)
 
+test_begin_subtest Don't exclude \deleted\ messages from search if not 
configured
+test_subtest_known_broken
+notmuch config set search.exclude_tags
+output=$(notmuch search subject:deleted | notmuch_search_sanitize)
+test_expect_equal $output thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; 
Not deleted (inbox unread)
+thread:XXX   2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox 
unread)
+
 test_done
-- 
1.7.8.1

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


[PATCH v2 3/6] config: only exclude messages if 'search.exclude_tags' is explicitly set

2012-01-22 Thread Pieter Praet
Currently, the 'search.exclude_tags' option is automatically
set to deleted;spam; if it's missing from the config file.

This violates the Principle of Least Surprise, so *only* set
'search.exclude_tags' to deleted;spam; if we didn't find a
configuration file at all.

This patch is actually Austin Clements' work:
  id:20120117203211.gq16...@mit.edu
---
 notmuch-config.c |8 ++--
 test/search  |1 -
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/notmuch-config.c b/notmuch-config.c
index 39da888..0ded6d7 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -362,8 +362,12 @@ notmuch_config_open (void *ctx,
 }
 
 if (notmuch_config_get_search_exclude_tags (config, tmp) == NULL) {
-   const char *tags[] = { deleted, spam };
-   notmuch_config_set_search_exclude_tags (config, tags, 2);
+   if (is_new) {
+   const char *tags[] = { deleted, spam };
+   notmuch_config_set_search_exclude_tags (config, tags, 2);
+   } else {
+   notmuch_config_set_search_exclude_tags (config, NULL, 0);
+   }
 }
 
 error = NULL;
diff --git a/test/search b/test/search
index 99d94bd..414be35 100755
--- a/test/search
+++ b/test/search
@@ -149,7 +149,6 @@ test_expect_equal $output thread:XXX   2001-01-05 [1/1] 
Notmuch Test Suite; N
 thread:XXX   2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted 
inbox unread)
 
 test_begin_subtest Don't exclude \deleted\ messages from search if not 
configured
-test_subtest_known_broken
 notmuch config set search.exclude_tags
 output=$(notmuch search subject:deleted | notmuch_search_sanitize)
 test_expect_equal $output thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; 
Not deleted (inbox unread)
-- 
1.7.8.1

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


[PATCH v2 4/6] setup: move tag printing and parsing into separate functions

2012-01-22 Thread Pieter Praet
From: Austin Clements amdra...@mit.edu

* notmuch-setup.c (notmuch_setup_command):
  Break tag printing and response parsing out into separate functions
  called `print_tag_list' respectively `parse_tag_list', for reuse
  with the 'search.exclude_tags' option.

---
 notmuch-setup.c |   55 ++-
 1 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/notmuch-setup.c b/notmuch-setup.c
index c3ea937..dcfa607 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -87,6 +87,38 @@ welcome_message_post_setup (void)
 have sufficient storage space available now.\n\n);
 }
 
+static void
+print_tag_list (const char **tags, size_t tags_len)
+{
+unsigned int i;
+for (i = 0; i  tags_len; i++) {
+   if (i != 0)
+   printf ( );
+   printf (%s, tags[i]);
+}
+}
+
+static GPtrArray *
+parse_tag_list (void *ctx, char *response)
+{
+GPtrArray *tags = g_ptr_array_new ();
+char *tag = response;
+char *space;
+
+while (tag  *tag) {
+   space = strchr (tag, ' ');
+   if (space)
+   g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag));
+   else
+   g_ptr_array_add (tags, talloc_strdup (ctx, tag));
+   tag = space;
+   while (tag  *tag == ' ')
+   tag++;
+}
+
+return tags;
+}
+
 int
 notmuch_setup_command (unused (void *ctx),
   unused (int argc), unused (char *argv[]))
@@ -164,30 +196,11 @@ notmuch_setup_command (unused (void *ctx),
 new_tags = notmuch_config_get_new_tags (config, new_tags_len);
 
 printf (Tags to apply to all new messages (separated by spaces) [);
-
-for (i = 0; i  new_tags_len; i++) {
-   if (i != 0)
-   printf ( );
-   printf (%s, new_tags[i]);
-}
-
+print_tag_list(new_tags, new_tags_len);
 prompt (]: );
 
 if (strlen (response)) {
-   GPtrArray *tags = g_ptr_array_new ();
-   char *tag = response;
-   char *space;
-
-   while (tag  *tag) {
-   space = strchr (tag, ' ');
-   if (space)
-   g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag));
-   else
-   g_ptr_array_add (tags, talloc_strdup (ctx, tag));
-   tag = space;
-   while (tag  *tag == ' ')
-   tag++;
-   }
+   GPtrArray *tags = parse_tag_list (ctx, response);
 
notmuch_config_set_new_tags (config, (const char **) tags-pdata,
 tags-len);
-- 
1.7.8.1

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


[PATCH v2 5/6] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Pieter Praet
Allow users to customize the search.exclude_tags option during setup.
---
 notmuch-setup.c |   21 +
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/notmuch-setup.c b/notmuch-setup.c
index dcfa607..0d75adc 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -133,6 +133,8 @@ notmuch_setup_command (unused (void *ctx),
 int is_new;
 const char **new_tags;
 size_t new_tags_len;
+const char **search_exclude_tags;
+size_t search_exclude_tags_len;
 
 #define prompt(format, ...)\
 do {   \
@@ -208,6 +210,25 @@ notmuch_setup_command (unused (void *ctx),
g_ptr_array_free (tags, TRUE);
 }
 
+
+search_exclude_tags = notmuch_config_get_search_exclude_tags (config, 
search_exclude_tags_len);
+
+printf (Tags to exclude when searching messages (separated by spaces) [);
+print_tag_list(search_exclude_tags, search_exclude_tags_len);
+prompt (]: );
+
+if (strlen (response)) {
+   GPtrArray *tags = parse_tag_list (ctx, response);
+
+   notmuch_config_set_search_exclude_tags (config,
+   (const char **)
+   tags-pdata,
+   tags-len);
+
+   g_ptr_array_free (tags, TRUE);
+}
+
+
 if (! notmuch_config_save (config)) {
if (is_new)
  welcome_message_post_setup ();
-- 
1.7.8.1

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


[PATCH v2 6/6] NEWS: update Tag exclusion section

2012-01-22 Thread Pieter Praet
---
 NEWS |   14 ++
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 2c2d9e9..a0b7929 100644
--- a/NEWS
+++ b/NEWS
@@ -13,10 +13,16 @@ Reply to sender
 
 Tag exclusion
 
-  Tags can be automatically excluded from search results unless they
-  appear explicitly in a query.  By default, notmuch excludes the tags
-  deleted and spam.  This can be changed using the new config setting
-  search.auto_exclude_tags.
+  Tags can be automatically excluded from search results by adding them
+  to the new 'search.exclude_tags' option in the Notmuch config file.
+
+  This behaviour can be overridden by explicitly including an excluded
+  tag in your query, for example:
+
+notmuch search $your_query and tag:$excluded_tag
+
+  Existing users will probably want to run notmuch setup again to add
+  the new well-commented [search] section to the configuration file.
 
 Emacs Interface
 ---
-- 
1.7.8.1

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


[PATCH] test/emacs-large-search-buffer: correct typo (EXPEXTED - EXPECTED)

2012-01-22 Thread Pieter Praet
introduced in commit 3b24b396
---
 test/emacs-large-search-buffer |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/test/emacs-large-search-buffer b/test/emacs-large-search-buffer
index 6095e9d..4351e33 100755
--- a/test/emacs-large-search-buffer
+++ b/test/emacs-large-search-buffer
@@ -19,25 +19,25 @@ done
 notmuch new  /dev/null
 
 test_begin_subtest Ensure that emacs doesn't drop results
-notmuch search '*'  EXPEXTED
-sed -i -e 's/^thread:[0-9a-f]*  //' -e 's/;//' -e 's/xx*/[BLOB]/' EXPEXTED
-echo 'End of search results.'  EXPEXTED
+notmuch search '*'  EXPECTED
+sed -i -e 's/^thread:[0-9a-f]*  //' -e 's/;//' -e 's/xx*/[BLOB]/' EXPECTED
+echo 'End of search results.'  EXPECTED
 
 test_emacs '(notmuch-search *)
(notmuch-test-wait)
(test-output)'
 sed -i -e s',  *, ,g' -e 's/xxx*/[BLOB]/g' OUTPUT
-test_expect_equal_file OUTPUT EXPEXTED
+test_expect_equal_file OUTPUT EXPECTED
 
 test_begin_subtest Ensure that emacs doesn't drop error messages
 test_emacs '(notmuch-search --this-option-does-not-exist)
(notmuch-test-wait)
(test-output)'
-cat EOF EXPEXTED
+cat EOF EXPECTED
 Error: Unexpected output from notmuch search:
 Unrecognized option: --this-option-does-not-exist
 End of search results. (process returned 1)
 EOF
-test_expect_equal_file OUTPUT EXPEXTED
+test_expect_equal_file OUTPUT EXPECTED
 
 test_done
-- 
1.7.8.1

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


Re: [PATCH v2 5/6] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Austin Clements
Quoth Pieter Praet on Jan 23 at  5:22 am:
 Allow users to customize the search.exclude_tags option during setup.
 ---
  notmuch-setup.c |   21 +
  1 files changed, 21 insertions(+), 0 deletions(-)
 
 diff --git a/notmuch-setup.c b/notmuch-setup.c
 index dcfa607..0d75adc 100644
 --- a/notmuch-setup.c
 +++ b/notmuch-setup.c
 @@ -133,6 +133,8 @@ notmuch_setup_command (unused (void *ctx),
  int is_new;
  const char **new_tags;
  size_t new_tags_len;
 +const char **search_exclude_tags;
 +size_t search_exclude_tags_len;
  
  #define prompt(format, ...)  \
  do { \
 @@ -208,6 +210,25 @@ notmuch_setup_command (unused (void *ctx),
   g_ptr_array_free (tags, TRUE);
  }
  
 +
 +search_exclude_tags = notmuch_config_get_search_exclude_tags (config, 
 search_exclude_tags_len);
 +
 +printf (Tags to exclude when searching messages (separated by spaces) 
 [);
 +print_tag_list(search_exclude_tags, search_exclude_tags_len);

Missing space before paren.

 +prompt (]: );
 +
 +if (strlen (response)) {
 + GPtrArray *tags = parse_tag_list (ctx, response);
 +
 + notmuch_config_set_search_exclude_tags (config,
 + (const char **)
 + tags-pdata,

No newline is needed between the case and the value.

 + tags-len);
 +
 + g_ptr_array_free (tags, TRUE);
 +}
 +
 +
  if (! notmuch_config_save (config)) {
   if (is_new)
 welcome_message_post_setup ();
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2 6/6] NEWS: update Tag exclusion section

2012-01-22 Thread Austin Clements
Quoth Pieter Praet on Jan 23 at  5:22 am:
 ---
  NEWS |   14 ++
  1 files changed, 10 insertions(+), 4 deletions(-)
 
 diff --git a/NEWS b/NEWS
 index 2c2d9e9..a0b7929 100644
 --- a/NEWS
 +++ b/NEWS
 @@ -13,10 +13,16 @@ Reply to sender
  
  Tag exclusion
  
 -  Tags can be automatically excluded from search results unless they
 -  appear explicitly in a query.  By default, notmuch excludes the tags
 -  deleted and spam.  This can be changed using the new config setting
 -  search.auto_exclude_tags.
 +  Tags can be automatically excluded from search results by adding them
 +  to the new 'search.exclude_tags' option in the Notmuch config file.
 +
 +  This behaviour can be overridden by explicitly including an excluded
 +  tag in your query, for example:
 +
 +notmuch search $your_query and tag:$excluded_tag
 +
 +  Existing users will probably want to run notmuch setup again to add
 +  the new well-commented [search] section to the configuration file.

Should probably add something about the default for new
configurations.  This also gives existing users an idea of what to set
this to if they want to follow the conventions used by new
configurations.  Maybe just add

In new configurations, this defaults to deleted and spam.

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


Re: [PATCH 3/4] config: only set search.exclude_tags to deleted; spam; during setup

2012-01-22 Thread Jameson Graef Rollins
On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet pie...@praet.org wrote:
 You definitely have a point, but then again, who are we to assume that
 the terms deleted and spam have the *exact* same meaning for
 everyone?  (also see id:8739bbo0br@praet.org)

Hrm.  I'm not sure I buy this.  Words already have meanings.  If we're
going to start down a rabbit hole where we have to assume that users are
making up crazy alternate meanings for words, we're going to run into a
lot of problems.

Notmuch, or at least the emacs interface, already assumes a specific
meaning for certain terms, like most notably inbox.  Given that we're
dealing with english here, I think we have to assume common usage
meanings for any of the words we're using to describe anything.

This argument breaks a little in regards to delete since we're not
actually deleting anything in the sense of rm'ing it form the
filesystem, so we're already changing the meaning a bit.  But see below.

 IMHO, this is one of those options that should remain disabled until
 *explicitly* set by the user.

Ok, but then we're back to the incredibly prolonged discussion we've
been having about adding delete keys.  If we disable this by default,
but add delete keys, the user might be in for a different surprise if
deleted messages keep showing up in searches.

Basically we have two options as I see it:

- add keys bindings to add deleted tags, and then *also* exclude
  tag:deleted by default.

- don't exclude anything by default, but then don't add any special keys
  to handle deleted tags.

There seemed to be a consensus forming that we in fact did want to add
the deleted key bindings.  If we do that, then I think we should
generate the config file to exclude deleted tags by default.

jamie.

PS: when I say exclude tags by default I actually mean that the
setting should be added to the config file upon (re)generation.  Nothing
should be excluded if nothing is set in the config file.


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


[PATCH v3 5/6] setup: prompt user for search.exclude_tags value

2012-01-22 Thread Pieter Praet
Allow users to customize the search.exclude_tags option during setup.

---

v2:
- less copy-paste coding... :)

v3: Austin's corrections [1]
- @ `print_tag_list':
  add space before paren.

- @ `notmuch_config_set_search_exclude_tags':
  remove \n between type cast and value.

[1] id:20120123043435.gr16...@mit.edu

 notmuch-setup.c |   20 
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/notmuch-setup.c b/notmuch-setup.c
index dcfa607..2941c52 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -133,6 +133,8 @@ notmuch_setup_command (unused (void *ctx),
 int is_new;
 const char **new_tags;
 size_t new_tags_len;
+const char **search_exclude_tags;
+size_t search_exclude_tags_len;
 
 #define prompt(format, ...)\
 do {   \
@@ -208,6 +210,24 @@ notmuch_setup_command (unused (void *ctx),
g_ptr_array_free (tags, TRUE);
 }
 
+
+search_exclude_tags = notmuch_config_get_search_exclude_tags (config, 
search_exclude_tags_len);
+
+printf (Tags to exclude when searching messages (separated by spaces) [);
+print_tag_list (search_exclude_tags, search_exclude_tags_len);
+prompt (]: );
+
+if (strlen (response)) {
+   GPtrArray *tags = parse_tag_list (ctx, response);
+
+   notmuch_config_set_search_exclude_tags (config,
+   (const char **) tags-pdata,
+   tags-len);
+
+   g_ptr_array_free (tags, TRUE);
+}
+
+
 if (! notmuch_config_save (config)) {
if (is_new)
  welcome_message_post_setup ();
-- 
1.7.8.1

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


[PATCH v3 6/6] NEWS: update Tag exclusion section

2012-01-22 Thread Pieter Praet
---

Added note re new configurations, as suggested by Austin:
  id:20120123044108.gs16...@mit.edu

 NEWS |   19 +++
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 2c2d9e9..2acdce5 100644
--- a/NEWS
+++ b/NEWS
@@ -13,10 +13,21 @@ Reply to sender
 
 Tag exclusion
 
-  Tags can be automatically excluded from search results unless they
-  appear explicitly in a query.  By default, notmuch excludes the tags
-  deleted and spam.  This can be changed using the new config setting
-  search.auto_exclude_tags.
+  Tags can be automatically excluded from search results by adding them
+  to the new 'search.exclude_tags' option in the Notmuch config file.
+
+  This behaviour can be overridden by explicitly including an excluded
+  tag in your query, for example:
+
+notmuch search $your_query and tag:$excluded_tag
+
+  Existing users will probably want to run notmuch setup again to add
+  the new well-commented [search] section to the configuration file.
+
+  For new configurations, accepting the default setting will cause the
+  tags deleted and spam to be excluded, equivalent to running:
+
+notmuch config set search.exclude_tags deleted spam
 
 Emacs Interface
 ---
-- 
1.7.8.1

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


  1   2   >