[PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Jani Nikula

Hi Mark -

This is my first look at any version of the series; apologies if I'm
clueless about some details... Please find some comments below.

BR,
Jani.


On Thu,  2 Feb 2012 17:43:35 +, Mark Walters  
wrote:
> The function is
> notmuch_thread_get_flag_messages
> (notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)
> 
> and returns the number of messages with the specified flags on flag_mask.

Is the purpose of this function to get the count of messages that have
certain flags set, certain flags not set, and certain flags don't-care?

At the very least, I think the documentation of the function should be
greatly improved.

I think the name of the function should be notmuch_thread_count_messages
which is like notmuch_query_count_messages, but for messages in threads
(and with some extra restrictions).

> 
> This generalises the existing function
> notmuch_thread_get_total_messages and
> notmuch_thread_get_matched_messages which are retained to maintain
> compatibility.
> ---
>  lib/message.cc |6 +++---
>  lib/notmuch.h  |   15 +--
>  lib/thread.cc  |   39 ++-
>  3 files changed, 42 insertions(+), 18 deletions(-)
> 
> diff --git a/lib/message.cc b/lib/message.cc
> index 0075425..d60da83 100644
> --- a/lib/message.cc
> +++ b/lib/message.cc
> @@ -746,7 +746,7 @@ notmuch_bool_t
>  notmuch_message_get_flag (notmuch_message_t *message,
> notmuch_message_flag_t flag)
>  {
> -return message->flags & (1 << flag);
> +return message->flags & flag;
>  }
>  
>  void
> @@ -754,9 +754,9 @@ notmuch_message_set_flag (notmuch_message_t *message,
> notmuch_message_flag_t flag, notmuch_bool_t enable)
>  {
>  if (enable)
> - message->flags |= (1 << flag);
> + message->flags |= flag;
>  else
> - message->flags &= ~(1 << flag);
> + message->flags &= ~flag;
>  }
>  
>  time_t
> diff --git a/lib/notmuch.h b/lib/notmuch.h
> index f75afae..c02e7f4 100644
> --- a/lib/notmuch.h
> +++ b/lib/notmuch.h
> @@ -654,6 +654,16 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread);
>  int
>  notmuch_thread_get_total_messages (notmuch_thread_t *thread);
>  
> +/* Get the number of messages in 'thread' which have the specified
> + * flags on flag_mask.
> + *
> + * This is a more general interface than
> + * notmuch_thread_get_total_messages or
> + * notmuch_thread_get_matched_messages
> + */
> +int
> +notmuch_thread_get_flag_messages (notmuch_thread_t *thread, unsigned int 
> flag_mask, unsigned int flags);
> +
>  /* Get a notmuch_messages_t iterator for the top-level messages in
>   * 'thread'.
>   *
> @@ -902,8 +912,9 @@ notmuch_message_get_filenames (notmuch_message_t 
> *message);
>  
>  /* Message flags */
>  typedef enum _notmuch_message_flag {
> -NOTMUCH_MESSAGE_FLAG_MATCH,
> -NOTMUCH_MESSAGE_FLAG_EXCLUDED
> +NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
> +NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
> +NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)

How are these used by the current lib users at the moment? How will they
break with this change?

Please align the assignments. 

>  } notmuch_message_flag_t;
>  
>  /* Get a value of a flag for the email corresponding to 'message'. */
> diff --git a/lib/thread.cc b/lib/thread.cc
> index e976d64..542f7f4 100644
> --- a/lib/thread.cc
> +++ b/lib/thread.cc
> @@ -37,8 +37,7 @@ struct visible _notmuch_thread {
>  
>  notmuch_message_list_t *message_list;
>  GHashTable *message_hash;
> -int total_messages;
> -int matched_messages;
> +int flag_count_messages[NOTMUCH_MESSAGE_FLAG_MAX];
>  time_t oldest;
>  time_t newest;
>  };
> @@ -226,7 +225,6 @@ _thread_add_message (notmuch_thread_t *thread,
>  
>  _notmuch_message_list_add_message (thread->message_list,
>  talloc_steal (thread, message));
> -thread->total_messages++;
>  
>  g_hash_table_insert (thread->message_hash,
>xstrdup (notmuch_message_get_message_id (message)),
> @@ -319,21 +317,18 @@ _thread_add_matched_message (notmuch_thread_t *thread,
>  
>  date = notmuch_message_get_date (message);
>  
> -if (date < thread->oldest || ! thread->matched_messages) {
> +if (date < thread->oldest || ! notmuch_thread_get_matched_messages 
> (thread)) {
>   thread->oldest = date;
>   if (sort == NOTMUCH_SORT_OLDEST_FIRST)
>   _thread_set_subject_from_message (thread, message);
>  }
>  
> -if (date > thread->newest || ! thread->matched_messages) {
> +if (date > thread->newest || ! notmuch_thread_get_matched_messages 
> (thread)) {
>   thread->newest = date;
>   if (sort != NOTMUCH_SORT_OLDEST_FIRST)
>   _thread_set_subject_from_message (thread, message);
>  }
>  
> -if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
> - thread->matched_messages++;
> -
>  if (g_hash_table_lookup_extended (thread->message_hash,
>

[PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Mark Walters
On Fri, 03 Feb 2012 01:07:59 +0200, Jani Nikula  wrote:
> On Thu, 02 Feb 2012 22:27:36 +, Mark Walters  gmail.com> wrote:
> > On Thu, 02 Feb 2012 23:55:33 +0200, Jani Nikula  wrote:
> > > 
> > > Hi Mark -
> > > 
> > > This is my first look at any version of the series; apologies if I'm
> > > clueless about some details... Please find some comments below.
> > > 
> > > BR,
> > > Jani.
> > > 
> > > 
> > > On Thu,  2 Feb 2012 17:43:35 +, Mark Walters  > > gmail.com> wrote:
> > > > The function is
> > > > notmuch_thread_get_flag_messages
> > > > (notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)
> > > > 
> > > > and returns the number of messages with the specified flags on 
> > > > flag_mask.
> > > 
> > > Is the purpose of this function to get the count of messages that have
> > > certain flags set, certain flags not set, and certain flags don't-care?
> > 
> > Yes: I was trying to follow Austin's suggestion from
> > id:"20120124025331.GZ16740 at mit.edu" (although stupidly I didn't
> > follow his suggestion of a function name).
> > 
> > > At the very least, I think the documentation of the function should be
> > > greatly improved.
> > > 
> > > I think the name of the function should be notmuch_thread_count_messages
> > > which is like notmuch_query_count_messages, but for messages in threads
> > > (and with some extra restrictions).
> > 
> > Yes I like your name; before I change it do you (and others) prefer it
> > to Austin's suggestion of notmuch_thread_count_flags. Or we could even
> > be more verbose with something like
> > notmuch_thread_count_messages_with_flags
> 
> I'd like to make it clear that it's about message count. Not about
> getting flags, not about flag counts. _with_flags is a matter of taste,
> no strong opinions there.

I think I will go with notmuch_thread_count_messages as you suggest.

> > > >  /* Message flags */
> > > >  typedef enum _notmuch_message_flag {
> > > > -NOTMUCH_MESSAGE_FLAG_MATCH,
> > > > -NOTMUCH_MESSAGE_FLAG_EXCLUDED
> > > > +NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
> > > > +NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
> > > > +NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)
> > > 
> > > How are these used by the current lib users at the moment? How will they
> > > break with this change?

I will just comment on this: the *only* reason I put in
NOTMUCH_MESSAGE_FLAG_MAX was as a way of keeping track of the size of
the bitfield. If there is a better way do say!

> > The only existing flag is NOTMUCH_MESSAGE_FLAG_MATCH: that is currently
> > zero but in the current code that is the bit offset of the flag; in my
> > version it is the actual bit for the flag (otherwise I think flag masks
> > end up very ugly). I believe all callers use notmuch_message_set_flag
> > and notmuch_message_get_flag so they should not notice the difference.
> > 
> > > Please align the assignments. 
> > 
> > Will do.
> > 
> > > > @@ -457,8 +452,8 @@ _notmuch_thread_create (void *ctx,
> > > >  thread->message_hash = g_hash_table_new_full (g_str_hash, 
> > > > g_str_equal,
> > > >   free, NULL);
> > > >  
> > > > -thread->total_messages = 0;
> > > > -thread->matched_messages = 0;
> > > > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> > > > +   thread->flag_count_messages[i] = 0;
> > > 
> > > memset (thread->flag_count_messages, 0, 
> > > sizeof(thread->flag_count_messages));
> > 
> > 
> > Will do 
> > 
> > > >  thread->oldest = 0;
> > > >  thread->newest = 0;
> > > >  
> > > > @@ -473,6 +468,7 @@ _notmuch_thread_create (void *ctx,
> > > >  notmuch_messages_move_to_next (messages))
> > > >  {
> > > > unsigned int doc_id;
> > > > +   unsigned int message_flags;
> > > >  
> > > > message = notmuch_messages_get (messages);
> > > > doc_id = _notmuch_message_get_doc_id (message);
> > > > @@ -485,6 +481,10 @@ _notmuch_thread_create (void *ctx,
> > > > _notmuch_doc_id_set_remove (match_set, doc_id);
> > > > _thread_add_matched_message (thread, message, sort);
> > > > }
> > > > +   message_flags =
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH) |
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_EXCLUDED);
> > > > +   thread->flag_count_messages[message_flags]++;
> > > 
> > > The first impression of using a set of flags as index is that there's a
> > > bug. But this is to keep count of messages with certain flag sets rather
> > > than total for each flag, right? I think this needs more comments, more
> > > documentation. Already naming the field flag_set_message_counts or
> > > similar would help greatly.
> > 
> > I will try and document it better: on first reading I parsed your name
> > as flag set (as verb) message counts whereas I assume you mean "flag
> > set" as a noun! I will see if I can come up with something though.
> 
> Yes, as a noun! :)

I

[PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Mark Walters
On Fri, 03 Feb 2012 01:13:31 +0200, Jani Nikula  wrote:
> On Thu, 02 Feb 2012 22:35:10 +, Mark Walters  gmail.com> wrote:
> > 
> > On Fri, 03 Feb 2012 00:08:32 +0200, Jani Nikula  wrote:
> > > On Thu,  2 Feb 2012 17:43:36 +, Mark Walters  > > gmail.com> wrote:
> > > > This adds the excludes to notmuch-show.c. We do not exclude when only
> > > > a single message (or part) is requested. notmuch-show will output the
> > > > exclude information when either text or json format is requested. As
> > > > this changes the output from notmuch-show it breaks many tests (in a
> > > > trivial and expected fashion).
> > > > ---
> > > >  notmuch-show.c |   24 
> > > >  1 files changed, 20 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/notmuch-show.c b/notmuch-show.c
> > > > index dec799c..108f13b 100644
> > > > --- a/notmuch-show.c
> > > > +++ b/notmuch-show.c
> > > > @@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, 
> > > > notmuch_message_t *message)
> > > >  static void
> > > >  format_message_text (unused (const void *ctx), notmuch_message_t 
> > > > *message, int indent)
> > > >  {
> > > > -printf ("id:%s depth:%d match:%d filename:%s\n",
> > > > +printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
> > > > notmuch_message_get_message_id (message),
> > > > indent,
> > > > -   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH),
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0,
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0,
> > > > notmuch_message_get_filename (message));
> > > >  }
> > > >  
> > > > @@ -212,9 +213,10 @@ format_message_json (const void *ctx, 
> > > > notmuch_message_t *message, unused (int in
> > > >  date = notmuch_message_get_date (message);
> > > >  relative_date = notmuch_time_relative_date (ctx, date);
> > > >  
> > > > -printf ("\"id\": %s, \"match\": %s, \"filename\": %s, 
> > > > \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
> > > > +printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, 
> > > > \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", 
> > > > \"tags\": [",
> > > > json_quote_str (ctx_quote, notmuch_message_get_message_id 
> > > > (message)),
> > > > notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false",
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false",
> > > > json_quote_str (ctx_quote, notmuch_message_get_filename 
> > > > (message)),
> > > > date, relative_date);
> > > >  
> > > > @@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int 
> > > > argc), unused (char *argv[]))
> > > >  char *opt;
> > > >  const notmuch_show_format_t *format = &format_text;
> > > >  notmuch_show_params_t params;
> > > > +const char **search_exclude_tags;
> > > > +size_t search_exclude_tags_length;
> > > 
> > > Please move these within the if (!no_exclude) block.
> > 
> > Will do. (I forgot to move them in notmuch-show when doing notmuch-count
> > and notmuch-search)
> > 
> > > >  int mbox = 0;
> > > >  int format_specified = 0;
> > > >  int i;
> > > > +notmuch_bool_t no_exclude = FALSE;
> > > > +unsigned int j;
> > > 
> > > Same. Or better yet, reuse i.
> > 
> > Will do.
> > 
> > > >  params.entire_thread = 0;
> > > >  params.raw = 0;
> > > > @@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int 
> > > > argc), unused (char *argv[]))
> > > > params.part = atoi(argv[i] + sizeof ("--part=") - 1);
> > > > } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
> > > > params.entire_thread = 1;
> > > > +   } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
> > > > +   no_exclude = TRUE;
> > > > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
> > > >(STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
> > > > if (params.cryptoctx == NULL) {
> > > > @@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int 
> > > > argc), unused (char *argv[]))
> > > >  if (params.raw && params.part < 0)
> > > > params.part = 0;
> > > >  
> > > > +/* If a single message is requested we do not use search_excludes. 
> > > > */
> > > >  if (params.part >= 0)
> > > > return do_show_single (ctx, query, format, ¶ms);
> > > > -else
> > > > +else {
> > > 
> > > Nitpick: There's no rule about this, but I do like the style of using
> > > braces for both branches if either branch needs them.
> > 
> > Will fix.
> > 
> > > > +   if (!no_exclude) {
> > > > +   search_exclude_tags = notmuch_config_get_search_exclude_tags
> > > > +   (config, &search_exclud

[PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Mark Walters

On Fri, 03 Feb 2012 00:08:32 +0200, Jani Nikula  wrote:
> On Thu,  2 Feb 2012 17:43:36 +, Mark Walters  gmail.com> wrote:
> > This adds the excludes to notmuch-show.c. We do not exclude when only
> > a single message (or part) is requested. notmuch-show will output the
> > exclude information when either text or json format is requested. As
> > this changes the output from notmuch-show it breaks many tests (in a
> > trivial and expected fashion).
> > ---
> >  notmuch-show.c |   24 
> >  1 files changed, 20 insertions(+), 4 deletions(-)
> > 
> > diff --git a/notmuch-show.c b/notmuch-show.c
> > index dec799c..108f13b 100644
> > --- a/notmuch-show.c
> > +++ b/notmuch-show.c
> > @@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, 
> > notmuch_message_t *message)
> >  static void
> >  format_message_text (unused (const void *ctx), notmuch_message_t *message, 
> > int indent)
> >  {
> > -printf ("id:%s depth:%d match:%d filename:%s\n",
> > +printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
> > notmuch_message_get_message_id (message),
> > indent,
> > -   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 
> > : 0,
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> > 1 : 0,
> > notmuch_message_get_filename (message));
> >  }
> >  
> > @@ -212,9 +213,10 @@ format_message_json (const void *ctx, 
> > notmuch_message_t *message, unused (int in
> >  date = notmuch_message_get_date (message);
> >  relative_date = notmuch_time_relative_date (ctx, date);
> >  
> > -printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": 
> > %ld, \"date_relative\": \"%s\", \"tags\": [",
> > +printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": 
> > %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
> > json_quote_str (ctx_quote, notmuch_message_get_message_id 
> > (message)),
> > notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 
> > "true" : "false",
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> > "true" : "false",
> > json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
> > date, relative_date);
> >  
> > @@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> >  char *opt;
> >  const notmuch_show_format_t *format = &format_text;
> >  notmuch_show_params_t params;
> > +const char **search_exclude_tags;
> > +size_t search_exclude_tags_length;
> 
> Please move these within the if (!no_exclude) block.

Will do. (I forgot to move them in notmuch-show when doing notmuch-count
and notmuch-search)

> >  int mbox = 0;
> >  int format_specified = 0;
> >  int i;
> > +notmuch_bool_t no_exclude = FALSE;
> > +unsigned int j;
> 
> Same. Or better yet, reuse i.

Will do.

> >  params.entire_thread = 0;
> >  params.raw = 0;
> > @@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> > params.part = atoi(argv[i] + sizeof ("--part=") - 1);
> > } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
> > params.entire_thread = 1;
> > +   } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
> > +   no_exclude = TRUE;
> > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
> >(STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
> > if (params.cryptoctx == NULL) {
> > @@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> >  if (params.raw && params.part < 0)
> > params.part = 0;
> >  
> > +/* If a single message is requested we do not use search_excludes. */
> >  if (params.part >= 0)
> > return do_show_single (ctx, query, format, ¶ms);
> > -else
> > +else {
> 
> Nitpick: There's no rule about this, but I do like the style of using
> braces for both branches if either branch needs them.

Will fix.

> > +   if (!no_exclude) {
> > +   search_exclude_tags = notmuch_config_get_search_exclude_tags
> > +   (config, &search_exclude_tags_length);
> > +   for (j = 0; j < search_exclude_tags_length; j++)
> > +   notmuch_query_add_tag_exclude (query, search_exclude_tags[j]);
> > +   }
> > return do_show (ctx, query, format, ¶ms);
> > +}
> 
> Hmm, unreachable code below. Why doesn't the compiler complain?

Yes I wondered about that (id:"20120120171801.GA16740 at mit.edu"): but didn't 
think I should do anything about
that in this series.

Thanks

Mark



[PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Mark Walters
On Thu, 02 Feb 2012 23:55:33 +0200, Jani Nikula  wrote:
> 
> Hi Mark -
> 
> This is my first look at any version of the series; apologies if I'm
> clueless about some details... Please find some comments below.
> 
> BR,
> Jani.
> 
> 
> On Thu,  2 Feb 2012 17:43:35 +, Mark Walters  gmail.com> wrote:
> > The function is
> > notmuch_thread_get_flag_messages
> > (notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)
> > 
> > and returns the number of messages with the specified flags on flag_mask.
> 
> Is the purpose of this function to get the count of messages that have
> certain flags set, certain flags not set, and certain flags don't-care?

Yes: I was trying to follow Austin's suggestion from
id:"20120124025331.GZ16740 at mit.edu" (although stupidly I didn't
follow his suggestion of a function name).

> At the very least, I think the documentation of the function should be
> greatly improved.
> 
> I think the name of the function should be notmuch_thread_count_messages
> which is like notmuch_query_count_messages, but for messages in threads
> (and with some extra restrictions).

Yes I like your name; before I change it do you (and others) prefer it
to Austin's suggestion of notmuch_thread_count_flags. Or we could even
be more verbose with something like
notmuch_thread_count_messages_with_flags

> >  /* Message flags */
> >  typedef enum _notmuch_message_flag {
> > -NOTMUCH_MESSAGE_FLAG_MATCH,
> > -NOTMUCH_MESSAGE_FLAG_EXCLUDED
> > +NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
> > +NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
> > +NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)
> 
> How are these used by the current lib users at the moment? How will they
> break with this change?

The only existing flag is NOTMUCH_MESSAGE_FLAG_MATCH: that is currently
zero but in the current code that is the bit offset of the flag; in my
version it is the actual bit for the flag (otherwise I think flag masks
end up very ugly). I believe all callers use notmuch_message_set_flag
and notmuch_message_get_flag so they should not notice the difference.

> Please align the assignments. 

Will do.

> > @@ -457,8 +452,8 @@ _notmuch_thread_create (void *ctx,
> >  thread->message_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
> >   free, NULL);
> >  
> > -thread->total_messages = 0;
> > -thread->matched_messages = 0;
> > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> > +   thread->flag_count_messages[i] = 0;
> 
> memset (thread->flag_count_messages, 0, sizeof(thread->flag_count_messages));


Will do 

> >  thread->oldest = 0;
> >  thread->newest = 0;
> >  
> > @@ -473,6 +468,7 @@ _notmuch_thread_create (void *ctx,
> >  notmuch_messages_move_to_next (messages))
> >  {
> > unsigned int doc_id;
> > +   unsigned int message_flags;
> >  
> > message = notmuch_messages_get (messages);
> > doc_id = _notmuch_message_get_doc_id (message);
> > @@ -485,6 +481,10 @@ _notmuch_thread_create (void *ctx,
> > _notmuch_doc_id_set_remove (match_set, doc_id);
> > _thread_add_matched_message (thread, message, sort);
> > }
> > +   message_flags =
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) |
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED);
> > +   thread->flag_count_messages[message_flags]++;
> 
> The first impression of using a set of flags as index is that there's a
> bug. But this is to keep count of messages with certain flag sets rather
> than total for each flag, right? I think this needs more comments, more
> documentation. Already naming the field flag_set_message_counts or
> similar would help greatly.

I will try and document it better: on first reading I parsed your name
as flag set (as verb) message counts whereas I assume you mean "flag
set" as a noun! I will see if I can come up with something though.

> > _notmuch_message_close (message);
> >  }
> > @@ -511,15 +511,28 @@ notmuch_thread_get_thread_id (notmuch_thread_t 
> > *thread)
> >  }
> >  
> >  int
> > +notmuch_thread_get_flag_messages (notmuch_thread_t *thread, unsigned int 
> > flag_mask, unsigned int flags)
> > +{
> > +unsigned int i;
> > +int count = 0;
> > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> 
> ARRAY_SIZE (thread->flag_count_messages)

ok

> 
> > +   if ((i & flag_mask) == (flags & flag_mask))
> > +   count += thread->flag_count_messages[i];
> > +return count;
> > +}
> 
> I wonder if the same could be accomplished by using two flag mask
> parameters, include_flag_mask and exclude_flag_mask. I'm thinking of the
> usage, would it be easier to use:
> 
> notmuch_query_count_messages (thread, NOTMUCH_MESSAGE_FLAG_MATCH, 
> NOTMUCH_MESSAGE_FLAG_EXCLUDED);
> 
> to get number of messages that have MATCH but not EXCLUDED? 0 as
> include_flag_mask could still be special for "all", and you could use:
> 
> notmuch_query_count_messages (thread, 0, NOTMUCH_MESSAG

[PATCH v5] add support for user-specified files & directories to ignore

2012-02-02 Thread Tomi Ollila
A new configuration key 'new.ignore' is used to determine which
files and directories user wants not to be scanned as new mails.

Mark the corresponding test as no longer broken
(test from id:"1328105573-4626-1-git-send-email-pieter at praet.org" ).

This work merges my previous attempts and Andreas Amann's work
in id:"ylp7hi23mw8.fsf at tyndall.ie"

See notes in id:"20120202-new-ignore-1-git-send-email-too at iki.fi"
---
 notmuch-client.h |9 +
 notmuch-config.c |   30 +-
 notmuch-new.c|   45 +
 test/new |1 -
 4 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index e0eb594..f1762ae 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -250,6 +250,15 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
 const char *new_tags[],
 size_t length);

+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config,
+  size_t *length);
+
+void
+notmuch_config_set_new_ignore (notmuch_config_t *config,
+  const char *new_ignore[],
+  size_t length);
+
 notmuch_bool_t
 notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);

diff --git a/notmuch-config.c b/notmuch-config.c
index a124e34..1f01128 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -44,7 +44,10 @@ static const char new_config_comment[] =
 " The following options are supported here:\n"
 "\n"
 "\ttagsA list (separated by ';') of the tags that will be\n"
-"\tadded to all messages incorporated by \"notmuch new\".\n";
+"\tadded to all messages incorporated by \"notmuch new\".\n"
+"\n"
+"\tignore  A list (separated by ';') of file and directory names\n"
+"\tthat will not be searched for messages by \"notmuch new\".\n";

 static const char user_config_comment[] =
 " User configuration\n"
@@ -105,6 +108,8 @@ struct _notmuch_config {
 size_t user_other_email_length;
 const char **new_tags;
 size_t new_tags_length;
+const char **new_ignore;
+size_t new_ignore_length;
 notmuch_bool_t maildir_synchronize_flags;
 const char **search_exclude_tags;
 size_t search_exclude_tags_length;
@@ -264,6 +269,8 @@ notmuch_config_open (void *ctx,
 config->user_other_email_length = 0;
 config->new_tags = NULL;
 config->new_tags_length = 0;
+config->new_ignore = NULL;
+config->new_ignore_length = 0;
 config->maildir_synchronize_flags = TRUE;
 config->search_exclude_tags = NULL;
 config->search_exclude_tags_length = 0;
@@ -361,6 +368,10 @@ notmuch_config_open (void *ctx,
notmuch_config_set_new_tags (config, tags, 2);
 }

+if (notmuch_config_get_new_ignore (config, &tmp) == NULL) {
+   notmuch_config_set_new_ignore (config, NULL, 0);
+}
+
 if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) {
if (is_new) {
const char *tags[] = { "deleted", "spam" };
@@ -609,6 +620,14 @@ notmuch_config_get_new_tags (notmuch_config_t *config,   
size_t *length)
 &(config->new_tags_length), length);
 }

+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config, size_t *length)
+{
+return _config_get_list (config, "new", "ignore",
+&(config->new_ignore),
+&(config->new_ignore_length), length);
+}
+
 void
 notmuch_config_set_user_other_email (notmuch_config_t *config,
 const char *list[],
@@ -627,6 +646,15 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
 &(config->new_tags));
 }

+void
+notmuch_config_set_new_ignore (notmuch_config_t *config,
+  const char *list[],
+  size_t length)
+{
+_config_set_list (config, "new", "ignore", list, length,
+&(config->new_ignore));
+}
+
 const char **
 notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t 
*length)
 {
diff --git a/notmuch-new.c b/notmuch-new.c
index a569a54..8a615e6 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -39,6 +39,8 @@ typedef struct {
 int verbose;
 const char **new_tags;
 size_t new_tags_length;
+const char **new_ignore;
+size_t new_ignore_length;

 int total_files;
 int processed_files;
@@ -181,6 +183,20 @@ _entries_resemble_maildir (struct dirent **entries, int 
count)
 return 0;
 }

+/* Test if the file/directory is to be ignor

Set "From" based on "To" when replying

2012-02-02 Thread Jani Nikula
On Sat, 21 Jan 2012 16:35:10 +0100, Simon Campese  wrote:
> Dear Community,
> 
> I've got my own domain and when registering or shopping at some website,
> I always use email addresses of the form "websitename at mydomain.org", so
> for example I use "amazon at mydomain.org" when shopping at amazon. The
> reason for this is categorizing incoming mail on the one hand, and
> immediately being able to spot the source of spam on the other hand. 
> 
> I would like to implement the following behaviour: When replying to a
> mail that has "something at mydomain.org" in the "To"-header, I would like
> to have the "From"-header of the reply to be automatically set to this
> address. 
> 
> Is there some kind of reply-hook in notmuch where one could put an
> appropriate function? 

Do you have all those email addresses in the user.other_email
configuration option in your ~/.notmuch-config? It should do the trick,
though I can see that it might get a bit tedious if you use plenty of
email addresses like above.

BR,
Jani.


[PATCH] add support for user-specified files & directories to ignore

2012-02-02 Thread Jani Nikula

Hi Tomi, please find a few more comments and nitpicks inline. No need to
roll another version for them, though.

BR,
Jani.

On Thu,  2 Feb 2012 17:17:33 +0200, Tomi Ollila  wrote:
> A new configuration key 'new.ignore' is used to determine which
> files and directories user wants not to be scanned as new mails.
> 
> Mark the corresponding test as no longer broken
> (test from id:"1328105573-4626-1-git-send-email-pieter at praet.org" ).
> 
> This work merges my previous attempts and Andreas Amann's work
> in id:"ylp7hi23mw8.fsf at tyndall.ie"
> 
> See notes in id:"20120202-new-ignore-1-git-send-email-too at iki.fi"
> ---
> 
> Whenever some already existing directory is added to the exclude list
> and the parent directory timestamp has not changed, notmuch new will not
> notice the directory has gone (as it still is there), user needs to 'touch'
> the parent directory before next 'notmuch new' no make notmuch notice.
> 
> 2012-01-26: could notmuch track mtime of the configuration file and if
> that changes, ignore mail directory timestamps ?
> 
> See previous notes in id:"20120131-new-ignore-1-git-send-email-too at iki.fi"
> 
>  notmuch-client.h |   10 ++
>  notmuch-config.c |   33 +++--
>  notmuch-new.c|   45 +
>  test/new |1 -
>  4 files changed, 74 insertions(+), 15 deletions(-)
> 
> diff --git a/notmuch-client.h b/notmuch-client.h
> index e0eb594..26153df 100644
> --- a/notmuch-client.h
> +++ b/notmuch-client.h
> @@ -245,11 +245,21 @@ notmuch_config_set_user_other_email (notmuch_config_t 
> *config,
>  const char **
>  notmuch_config_get_new_tags (notmuch_config_t *config,
>size_t *length);
> +

Nitpick: unrelated change.

>  void
>  notmuch_config_set_new_tags (notmuch_config_t *config,
>const char *new_tags[],
>size_t length);
>  
> +const char **
> +notmuch_config_get_new_ignore (notmuch_config_t *config,
> +size_t *length);
> +
> +void
> +notmuch_config_set_new_ignore (notmuch_config_t *config,
> +const char *new_ignore[],
> +size_t length);
> +
>  notmuch_bool_t
>  notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);
>  
> diff --git a/notmuch-config.c b/notmuch-config.c
> index a124e34..1f01004 100644
> --- a/notmuch-config.c
> +++ b/notmuch-config.c
> @@ -44,7 +44,10 @@ static const char new_config_comment[] =
>  " The following options are supported here:\n"
>  "\n"
>  "\ttags  A list (separated by ';') of the tags that will be\n"
> -"\t  added to all messages incorporated by \"notmuch new\".\n";
> +"\t  added to all messages incorporated by \"notmuch new\".\n"
> +"\n"
> +"\tignoreA list (separated by ';') of file and directory names\n"
> +"\t  that will not be searched for messages by \"notmuch new\".\n";

Do I understand the code correctly, the ignore list must contain file
and directory names without (absolute or relative) paths? And that there
is no way to exclude only the subdirectory "foo" within directory "foo",
because they would both get ignored?

I don't see this as a bad thing, not at all. This keeps things nice and
simple, it just needs proper documentation.

>  
>  static const char user_config_comment[] =
>  " User configuration\n"
> @@ -105,6 +108,8 @@ struct _notmuch_config {
>  size_t user_other_email_length;
>  const char **new_tags;
>  size_t new_tags_length;
> +const char **new_ignore;
> +size_t new_ignore_length;
>  notmuch_bool_t maildir_synchronize_flags;
>  const char **search_exclude_tags;
>  size_t search_exclude_tags_length;
> @@ -264,6 +269,8 @@ notmuch_config_open (void *ctx,
>  config->user_other_email_length = 0;
>  config->new_tags = NULL;
>  config->new_tags_length = 0;
> +config->new_ignore = NULL;
> +config->new_ignore_length = 0;
>  config->maildir_synchronize_flags = TRUE;
>  config->search_exclude_tags = NULL;
>  config->search_exclude_tags_length = 0;
> @@ -361,6 +368,10 @@ notmuch_config_open (void *ctx,
>   notmuch_config_set_new_tags (config, tags, 2);
>  }
>  
> +if (notmuch_config_get_new_ignore (config, &tmp) == NULL) {
> + notmuch_config_set_new_ignore (config, NULL, 0);
> +}
> +
> 

BiDi

2012-02-02 Thread Clint Adams
On Thu, Feb 02, 2012 at 09:44:07AM -0800, Jameson Graef Rollins wrote:
> More info please.  What is "RTL script"?  Is that "right to left"?  If
> so, yikes.  I can't even imagine what a mess that would have looked
> like.  Another argument against this crazy indenting stuff we do.  I
> hope the thread was also indenting from the right!

Yes, right to left.

Presumably this will be fixed in emacs some year;
http://www.emacswiki.org/emacs/SupportBiDi


Possible bug in notmuch python, removing tags not working.

2012-02-02 Thread Justus Winter
Quoting Bryan Hunt (2012-02-01 18:23:11)
>https://bitbucket.org/spaetz/cnotmuch/issue/1/removing-tags-doesnt-seem-to-be-saving

errm... quoting the bug report:
> I've created a trivial python script on Ubuntu, using python-notmuch
> 0.6.1-1 (a bit old, I know).

Please update your notmuch installation and try to reproduce the
bug. If it is still an issue, I'll have a look at it.

Please note that I use the python bindings on a daily basis and have
no trouble adding or removing bugs.

Cheers,
Justus


[PATCH v2] emacs: add default value to notmuch-search-line-faces

2012-02-02 Thread Tomi Ollila
On Thu,  2 Feb 2012 16:58:41 +0200, Jani Nikula  wrote:
> Add default value to notmuch-search-line-faces to show "unread"
> messages in bold, and "flagged" messages in blue, to have some visual
> indication of important messages in search results. This should be
> helpful for new users.
> 
> "unread" tag is quite obvious, and handled specially both in the lib
> and emacs ui. "flagged" is synced to maildir F flag in the lib. If one
> syncs the maildir to IMAP, this also translates to corresponding IMAP
> flag. (This is "starred" in GMail and Android.)
> 
> Signed-off-by: Jani Nikula 
> ---

Works fine. +1

Tomi


[PATCH v4 11/11] emacs: show: recognize the exclude flag.

2012-02-02 Thread Mark Walters
Show mode will recognize the exclude flag by not opening excluding
messages by default, and will start at the first matching non-excluded
message. If there are no matching non-excluded messages it will go to
the first matching (necessarily excluded) message.
---
 emacs/notmuch-show.el |   18 +-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 84ac624..8efadf6 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -905,7 +905,8 @@ current buffer, if possible."

 ;; Message visibility depends on whether it matched the search
 ;; criteria.
-(notmuch-show-message-visible msg (plist-get msg :match
+(notmuch-show-message-visible msg (and (plist-get msg :match)
+  (not (plist-get msg :excluded))

 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
@@ -1015,6 +1016,9 @@ buffer."
 ;; Move straight to the first open message
 (unless (notmuch-show-message-visible-p)
   (notmuch-show-next-open-message))
+(when (eq (point) (point-max))
+  (goto-char (point-min))
+  (notmuch-show-next-matching-message))

 ;; Set the header line to the subject of the first open message.
 (setq header-line-format (notmuch-show-strip-re 
(notmuch-show-get-subject)))
@@ -1417,6 +1421,18 @@ any effects from previous calls to
  (notmuch-show-message-adjust))
   (goto-char (point-max)

+(defun notmuch-show-next-matching-message ()
+  "Show the next matching message."
+  (interactive)
+  (let (r)
+(while (and (setq r (notmuch-show-goto-message-next))
+   (not (notmuch-show-get-prop :match
+(if r
+   (progn
+ (notmuch-show-mark-read)
+ (notmuch-show-message-adjust))
+  (goto-char (point-max)
+
 (defun notmuch-show-previous-open-message ()
   "Show the previous message."
   (interactive)
-- 
1.7.2.3



[PATCH v4 10/11] cli: omit excluded messages in results where appropriate.

2012-02-02 Thread Mark Walters
In all cases of notmuch count/search/show where the results returned
cannot reflect the exclude flag return just the matched not-excluded
results. If the caller wishes to have all the matched results (i.e.,
including the excluded ones) they should call with the
--no-exclude option.

The relevant cases are
count: both threads and messages
search: all cases except the summary view
show: mbox format
---
 notmuch-count.c  |2 ++
 notmuch-search.c |9 +
 notmuch-show.c   |5 +
 3 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 5364507..46b76ae 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -88,6 +88,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
 }

+notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 switch (output) {
 case OUTPUT_MESSAGES:
printf ("%u\n", notmuch_query_count_messages (query));
diff --git a/notmuch-search.c b/notmuch-search.c
index 43ec90b..d2b2488 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -207,6 +207,9 @@ do_search_threads (const search_format_t *format,
 int first_thread = 1;
 int i;

+if (output == OUTPUT_THREADS)
+   notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 if (offset < 0) {
offset += notmuch_query_count_threads (query);
if (offset < 0)
@@ -297,6 +300,8 @@ do_search_messages (const search_format_t *format,
 int first_message = 1;
 int i;

+notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 if (offset < 0) {
offset += notmuch_query_count_messages (query);
if (offset < 0)
@@ -368,6 +373,10 @@ do_search_tags (notmuch_database_t *notmuch,
 const char *tag;
 int first_tag = 1;

+notmuch_query_set_omit_excluded_messages (query, TRUE);
+/* should the following only special case if no excluded terms
+ * specified? */
+
 /* Special-case query of "*" for better performance. */
 if (strcmp (notmuch_query_get_query_string (query), "*") == 0) {
tags = notmuch_database_get_all_tags (notmuch);
diff --git a/notmuch-show.c b/notmuch-show.c
index 108f13b..924e7ea 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1166,6 +1166,11 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
return 1;
 }

+/* if format=mbox then we can not output excluded messages as
+ * there is no way to make the exclude flag available */
+if (mbox)
+   notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 /* if part was requested and format was not specified, use format=raw */
 if (params.part >= 0 && !format_specified)
format = &format_raw;
-- 
1.7.2.3



[PATCH v4 09/11] test: update tests to reflect the exclude flag

2012-02-02 Thread Mark Walters
notmuch show outputs the exclude flag so many tests using notmuch
show failed. This commit adds "excluded:0" or "excluded: false" to
the expected outputs. After this commit there should be no failing
tests.
---
 test/crypto|9 -
 test/encoding  |2 +-
 test/json  |6 +++---
 test/maildir-sync  |1 +
 test/multipart |4 ++--
 test/thread-naming |   16 
 6 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/test/crypto b/test/crypto
index 446a58b..f29d959 100755
--- a/test/crypto
+++ b/test/crypto
@@ -43,6 +43,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -77,6 +78,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -113,6 +115,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -153,7 +156,7 @@ test_begin_subtest "decryption, --format=text"
 output=$(notmuch show --format=text --decrypt subject:"test encrypted message 
001" \
 | notmuch_show_sanitize_all \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
-expected='message{ id:X depth:0 match:1 filename:X
+expected='message{ id:X depth:0 match:1 excluded:0 filename:X
 header{
 Notmuch Test Suite  (2000-01-01) (encrypted 
inbox)
 Subject: test encrypted message 001
@@ -187,6 +190,7 @@ output=$(notmuch show --format=json --decrypt subject:"test 
encrypted message 00
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -242,6 +246,7 @@ output=$(notmuch show --format=json --decrypt subject:"test 
encrypted message 00
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -277,6 +282,7 @@ output=$(notmuch show --format=json --decrypt subject:"test 
encrypted message 00
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -332,6 +338,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
diff --git a/test/encoding b/test/encoding
index 33259c1..a872345 100755
--- a/test/encoding
+++ b/test/encoding
@@ -6,7 +6,7 @@ test_begin_subtest "Message with text of unknown charset"
 add_message '[content-type]="text/plain; charset=unknown-8bit"' \
"[body]=irrelevant"
 output=$(notmuch show id:${gen_msg_id} 2>&1 | notmuch_show_sanitize)
-test_expect_equal "$output" "message{ id:msg-001 at notmuch-test-suite 
depth:0 match:1 filename:/XXX/mail/msg-001
+test_expect_equal "$output" "message{ id:msg-001 at notmuch-test-suite 
depth:0 match:1 excluded:0 filename:/XXX/mail/msg-001
 header{
 Notmuch Test Suite  (2001-01-05) (inbox unread)
 Subject: Test message #1
diff --git a/test/json b/test/json
index 7df4380..f95fcf8 100755
--- a/test/json
+++ b/test/json
@@ -5,7 +5,7 @@ test_description="--format=json output"
 test_begin_subtest "Show message: json"
 add_message "[subject]=\"json-show-subject\"" "[date]=\"Sat, 01 Jan 2000 
12:00:00 -\"" "[body]=\"json-show-message\""
 output=$(notmuch show --format=json "json-show-message")
-test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, 
\"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, 
\"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], 
\"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test 
Suite \", \"To\": \"Notmuch Test Suite 
\", \"Cc\": \"\", \"Bcc\": \"\", \"Date\": 
\"Sat, 01 Jan 2000 12:00:00 -\"}, \"body\": [{\"id\": 1, \"content-type\": 
\"text/plain\", \"content\": \"json-show-message\n\"}]}, ["
+test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, 
\"excluded\": false, \"filename\": \"${gen_msg_filenam

[PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Mark Walters
This adds the excludes to notmuch-show.c. We do not exclude when only
a single message (or part) is requested. notmuch-show will output the
exclude information when either text or json format is requested. As
this changes the output from notmuch-show it breaks many tests (in a
trivial and expected fashion).
---
 notmuch-show.c |   24 
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index dec799c..108f13b 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, notmuch_message_t 
*message)
 static void
 format_message_text (unused (const void *ctx), notmuch_message_t *message, int 
indent)
 {
-printf ("id:%s depth:%d match:%d filename:%s\n",
+printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
notmuch_message_get_message_id (message),
indent,
-   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
+   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 
: 0,
+   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
1 : 0,
notmuch_message_get_filename (message));
 }

@@ -212,9 +213,10 @@ format_message_json (const void *ctx, notmuch_message_t 
*message, unused (int in
 date = notmuch_message_get_date (message);
 relative_date = notmuch_time_relative_date (ctx, date);

-printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, 
\"date_relative\": \"%s\", \"tags\": [",
+printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, 
\"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
json_quote_str (ctx_quote, notmuch_message_get_message_id 
(message)),
notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 
"true" : "false",
+   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
"true" : "false",
json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
date, relative_date);

@@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
 char *opt;
 const notmuch_show_format_t *format = &format_text;
 notmuch_show_params_t params;
+const char **search_exclude_tags;
+size_t search_exclude_tags_length;
 int mbox = 0;
 int format_specified = 0;
 int i;
+notmuch_bool_t no_exclude = FALSE;
+unsigned int j;

 params.entire_thread = 0;
 params.raw = 0;
@@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
params.part = atoi(argv[i] + sizeof ("--part=") - 1);
} else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
params.entire_thread = 1;
+   } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
+   no_exclude = TRUE;
} else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
   (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
if (params.cryptoctx == NULL) {
@@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
 if (params.raw && params.part < 0)
params.part = 0;

+/* If a single message is requested we do not use search_excludes. */
 if (params.part >= 0)
return do_show_single (ctx, query, format, ¶ms);
-else
+else {
+   if (!no_exclude) {
+   search_exclude_tags = notmuch_config_get_search_exclude_tags
+   (config, &search_exclude_tags_length);
+   for (j = 0; j < search_exclude_tags_length; j++)
+   notmuch_query_add_tag_exclude (query, search_exclude_tags[j]);
+   }
return do_show (ctx, query, format, ¶ms);
+}

 notmuch_query_destroy (query);
 notmuch_database_close (notmuch);
-- 
1.7.2.3



[PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Mark Walters
The function is
notmuch_thread_get_flag_messages
(notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)

and returns the number of messages with the specified flags on flag_mask.

This generalises the existing function
notmuch_thread_get_total_messages and
notmuch_thread_get_matched_messages which are retained to maintain
compatibility.
---
 lib/message.cc |6 +++---
 lib/notmuch.h  |   15 +--
 lib/thread.cc  |   39 ++-
 3 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 0075425..d60da83 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -746,7 +746,7 @@ notmuch_bool_t
 notmuch_message_get_flag (notmuch_message_t *message,
  notmuch_message_flag_t flag)
 {
-return message->flags & (1 << flag);
+return message->flags & flag;
 }

 void
@@ -754,9 +754,9 @@ notmuch_message_set_flag (notmuch_message_t *message,
  notmuch_message_flag_t flag, notmuch_bool_t enable)
 {
 if (enable)
-   message->flags |= (1 << flag);
+   message->flags |= flag;
 else
-   message->flags &= ~(1 << flag);
+   message->flags &= ~flag;
 }

 time_t
diff --git a/lib/notmuch.h b/lib/notmuch.h
index f75afae..c02e7f4 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -654,6 +654,16 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread);
 int
 notmuch_thread_get_total_messages (notmuch_thread_t *thread);

+/* Get the number of messages in 'thread' which have the specified
+ * flags on flag_mask.
+ *
+ * This is a more general interface than
+ * notmuch_thread_get_total_messages or
+ * notmuch_thread_get_matched_messages
+ */
+int
+notmuch_thread_get_flag_messages (notmuch_thread_t *thread, unsigned int 
flag_mask, unsigned int flags);
+
 /* Get a notmuch_messages_t iterator for the top-level messages in
  * 'thread'.
  *
@@ -902,8 +912,9 @@ notmuch_message_get_filenames (notmuch_message_t *message);

 /* Message flags */
 typedef enum _notmuch_message_flag {
-NOTMUCH_MESSAGE_FLAG_MATCH,
-NOTMUCH_MESSAGE_FLAG_EXCLUDED
+NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
+NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
+NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)
 } notmuch_message_flag_t;

 /* Get a value of a flag for the email corresponding to 'message'. */
diff --git a/lib/thread.cc b/lib/thread.cc
index e976d64..542f7f4 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -37,8 +37,7 @@ struct visible _notmuch_thread {

 notmuch_message_list_t *message_list;
 GHashTable *message_hash;
-int total_messages;
-int matched_messages;
+int flag_count_messages[NOTMUCH_MESSAGE_FLAG_MAX];
 time_t oldest;
 time_t newest;
 };
@@ -226,7 +225,6 @@ _thread_add_message (notmuch_thread_t *thread,

 _notmuch_message_list_add_message (thread->message_list,
   talloc_steal (thread, message));
-thread->total_messages++;

 g_hash_table_insert (thread->message_hash,
 xstrdup (notmuch_message_get_message_id (message)),
@@ -319,21 +317,18 @@ _thread_add_matched_message (notmuch_thread_t *thread,

 date = notmuch_message_get_date (message);

-if (date < thread->oldest || ! thread->matched_messages) {
+if (date < thread->oldest || ! notmuch_thread_get_matched_messages 
(thread)) {
thread->oldest = date;
if (sort == NOTMUCH_SORT_OLDEST_FIRST)
_thread_set_subject_from_message (thread, message);
 }

-if (date > thread->newest || ! thread->matched_messages) {
+if (date > thread->newest || ! notmuch_thread_get_matched_messages 
(thread)) {
thread->newest = date;
if (sort != NOTMUCH_SORT_OLDEST_FIRST)
_thread_set_subject_from_message (thread, message);
 }

-if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
-   thread->matched_messages++;
-
 if (g_hash_table_lookup_extended (thread->message_hash,
notmuch_message_get_message_id (message), NULL,
(void **) &hashed_message)) {
@@ -411,7 +406,7 @@ _notmuch_thread_create (void *ctx,
 const char *thread_id;
 char *thread_id_query_string;
 notmuch_query_t *thread_id_query;
-
+int i;
 notmuch_messages_t *messages;
 notmuch_message_t *message;

@@ -457,8 +452,8 @@ _notmuch_thread_create (void *ctx,
 thread->message_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
  free, NULL);

-thread->total_messages = 0;
-thread->matched_messages = 0;
+for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
+   thread->flag_count_messages[i] = 0;
 thread->oldest = 0;
 thread->newest = 0;

@@ -473,6 +468,7 @@ _notmuch_thread_create (void *ctx,
 notmuch_messages_move_to_next (messages))
 {
unsigned int doc_id;
+   unsigned int message_flags;

message = notmuch_message

[PATCH v4 06/11] lib: Add the exclude flag to notmuch_query_search_threads

2012-02-02 Thread Mark Walters
Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to
notmuch_query_search_threads. Implemented by inspecting the tags
directly in _notmuch_thread_create/_thread_add_message rather than as
a Xapian query for speed reasons.
---
 lib/notmuch-private.h |7 +--
 lib/query.cc  |1 +
 lib/thread.cc |   18 +++---
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index e791bb0..ea836f7 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -148,6 +148,8 @@ typedef enum _notmuch_private_status {

 typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;

+typedef struct _notmuch_string_list notmuch_string_list_t;
+
 /* database.cc */

 /* Lookup a prefix value by name.
@@ -216,6 +218,7 @@ _notmuch_thread_create (void *ctx,
notmuch_database_t *notmuch,
unsigned int seed_doc_id,
notmuch_doc_id_set_t *match_set,
+   notmuch_string_list_t *excluded_terms,
notmuch_sort_t sort);

 /* message.cc */
@@ -459,11 +462,11 @@ typedef struct _notmuch_string_node {
 struct _notmuch_string_node *next;
 } notmuch_string_node_t;

-typedef struct visible _notmuch_string_list {
+struct visible _notmuch_string_list {
 int length;
 notmuch_string_node_t *head;
 notmuch_string_node_t **tail;
-} notmuch_string_list_t;
+};

 notmuch_string_list_t *
 _notmuch_string_list_create (const void *ctx);
diff --git a/lib/query.cc b/lib/query.cc
index 90a71a1..e1c3977 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -472,6 +472,7 @@ notmuch_threads_get (notmuch_threads_t *threads)
   threads->query->notmuch,
   doc_id,
   &threads->match_set,
+  threads->query->exclude_terms,
   threads->query->sort);
 }

diff --git a/lib/thread.cc b/lib/thread.cc
index 0435ee6..e976d64 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread,
  */
 static void
 _thread_add_message (notmuch_thread_t *thread,
-notmuch_message_t *message)
+notmuch_message_t *message,
+notmuch_string_list_t *exclude_terms)
 {
 notmuch_tags_t *tags;
 const char *tag;
@@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread,
 notmuch_tags_move_to_next (tags))
 {
tag = notmuch_tags_get (tags);
+   /* Mark excluded messages. */
+   for (notmuch_string_node_t *term = exclude_terms->head; term;
+term = term->next) {
+   /* We ignore initial 'K'. */
+   if (strcmp(tag, (term->string + 1)) == 0) {
+   notmuch_message_set_flag (message, 
NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
+   break;
+   }
+   }
g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
 }
 }
@@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread,
_thread_set_subject_from_message (thread, message);
 }

-thread->matched_messages++;
+if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
+   thread->matched_messages++;

 if (g_hash_table_lookup_extended (thread->message_hash,
notmuch_message_get_message_id (message), NULL,
@@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx,
notmuch_database_t *notmuch,
unsigned int seed_doc_id,
notmuch_doc_id_set_t *match_set,
+   notmuch_string_list_t *exclude_terms,
notmuch_sort_t sort)
 {
 notmuch_thread_t *thread;
@@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx,
if (doc_id == seed_doc_id)
message = seed_message;

-   _thread_add_message (thread, message);
+   _thread_add_message (thread, message, exclude_terms);

if ( _notmuch_doc_id_set_contains (match_set, doc_id)) {
_notmuch_doc_id_set_remove (match_set, doc_id);
-- 
1.7.2.3



[PATCH v4 05/11] lib: Make notmuch_query_search_messages set the exclude flag

2012-02-02 Thread Mark Walters
Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by
notmuch_query_search_messages for excluded messages. Also add an
option omit_excluded_messages to the search that we do not want the
excludes at all.

This exclude flag will be added to notmuch_query_search threads in the
next patch.
---
 lib/notmuch-private.h |1 +
 lib/notmuch.h |   10 -
 lib/query.cc  |   52 +---
 3 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 7bf153e..e791bb0 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -401,6 +401,7 @@ typedef struct _notmuch_message_list {
  */
 struct visible _notmuch_messages {
 notmuch_bool_t is_of_list_type;
+notmuch_doc_id_set_t *excluded_doc_ids;
 notmuch_message_node_t *iterator;
 };

diff --git a/lib/notmuch.h b/lib/notmuch.h
index 7929fe7..f75afae 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -449,6 +449,13 @@ typedef enum {
 const char *
 notmuch_query_get_query_string (notmuch_query_t *query);

+/* Specify whether to results should omit the excluded results rather
+ * than just marking them excluded. This is useful for passing a
+ * notmuch_messages_t not containing the excluded messages to other
+ * functions. */
+void
+notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, 
notmuch_bool_t omit);
+
 /* Specify the sorting desired for this query. */
 void
 notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
@@ -895,7 +902,8 @@ notmuch_message_get_filenames (notmuch_message_t *message);

 /* Message flags */
 typedef enum _notmuch_message_flag {
-NOTMUCH_MESSAGE_FLAG_MATCH
+NOTMUCH_MESSAGE_FLAG_MATCH,
+NOTMUCH_MESSAGE_FLAG_EXCLUDED
 } notmuch_message_flag_t;

 /* Get a value of a flag for the email corresponding to 'message'. */
diff --git a/lib/query.cc b/lib/query.cc
index c25b301..90a71a1 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -28,6 +28,7 @@ struct _notmuch_query {
 const char *query_string;
 notmuch_sort_t sort;
 notmuch_string_list_t *exclude_terms;
+notmuch_bool_t omit_excluded_messages;
 };

 typedef struct _notmuch_mset_messages {
@@ -57,6 +58,12 @@ struct visible _notmuch_threads {
 notmuch_doc_id_set_t match_set;
 };

+/* We need this in the message functions so forward declare. */
+static notmuch_bool_t
+_notmuch_doc_id_set_init (void *ctx,
+ notmuch_doc_id_set_t *doc_ids,
+ GArray *arr);
+
 notmuch_query_t *
 notmuch_query_create (notmuch_database_t *notmuch,
  const char *query_string)
@@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch,

 query->exclude_terms = _notmuch_string_list_create (query);

+query->omit_excluded_messages = FALSE;
+
 return query;
 }

@@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query)
 }

 void
+notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, 
notmuch_bool_t omit)
+{
+query->omit_excluded_messages = omit;
+}
+
+void
 notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort)
 {
 query->sort = sort;
@@ -173,6 +188,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
   "mail"));
Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
+   Xapian::MSetIterator iterator;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
  Xapian::QueryParser::FLAG_PHRASE |
  Xapian::QueryParser::FLAG_LOVEHATE |
@@ -190,11 +206,35 @@ notmuch_query_search_messages (notmuch_query_t *query)
final_query = Xapian::Query (Xapian::Query::OP_AND,
 mail_query, string_query);
}
+   messages->base.excluded_doc_ids = NULL;
+
+   if (query->exclude_terms) {
+   exclude_query = _notmuch_exclude_tags (query, final_query);
+   exclude_query = Xapian::Query (Xapian::Query::OP_AND,
+  exclude_query, final_query);
+
+   if (query->omit_excluded_messages)
+   final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+final_query, exclude_query);
+   else {
+   enquire.set_weighting_scheme (Xapian::BoolWeight());
+   enquire.set_query (exclude_query);
+
+   mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount 
());
+
+   GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof 
(unsigned int));
+
+   for (iterator = mset.begin (); iterator != mset.end (); 
iterator++) {
+   unsigned int doc_id = *iterator;
+   g_array_append_val (excluded_doc_ids, doc_id);
+   }
+   messages->base.excluded_doc_ids = talloc (query, 
_notmuch_doc_id_s

[PATCH v4 04/11] lib: Rearrange the exclude code in query.cc

2012-02-02 Thread Mark Walters
Slightly refactor the exclude code to give the callers access to the
exclude query itself. There should be no functional change.
---
 lib/query.cc |   29 +++--
 1 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index 0b36602..c25b301 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -122,12 +122,15 @@ _notmuch_messages_destructor (notmuch_mset_messages_t 
*messages)
 return 0;
 }

-/* Return a query that does not match messages with the excluded tags
- * registered with the query.  Any tags that explicitly appear in
- * xquery will not be excluded. */
+/* Return a query that matches messages with the excluded tags
+ * registered with query.  Any tags that explicitly appear in xquery
+ * will not be excluded. The caller of this function has to combine
+ * the returned query appropriately.*/
 static Xapian::Query
 _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
 {
+Xapian::Query exclude_query = Xapian::Query::MatchNothing;
+
 for (notmuch_string_node_t *term = query->exclude_terms->head; term;
 term = term->next) {
Xapian::TermIterator it = xquery.get_terms_begin ();
@@ -137,10 +140,10 @@ _notmuch_exclude_tags (notmuch_query_t *query, 
Xapian::Query xquery)
break;
}
if (it == end)
-   xquery = Xapian::Query (Xapian::Query::OP_AND_NOT,
-   xquery, Xapian::Query (term->string));
+   exclude_query = Xapian::Query (Xapian::Query::OP_OR,
+   exclude_query, Xapian::Query 
(term->string));
 }
-return xquery;
+return exclude_query;
 }

 notmuch_messages_t *
@@ -168,7 +171,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
   _find_prefix ("type"),
   "mail"));
-   Xapian::Query string_query, final_query;
+   Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
  Xapian::QueryParser::FLAG_PHRASE |
@@ -188,7 +191,10 @@ notmuch_query_search_messages (notmuch_query_t *query)
 mail_query, string_query);
}

-   final_query = _notmuch_exclude_tags (query, final_query);
+   exclude_query = _notmuch_exclude_tags (query, final_query);
+
+   final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+final_query, exclude_query);

enquire.set_weighting_scheme (Xapian::BoolWeight());

@@ -449,7 +455,7 @@ notmuch_query_count_messages (notmuch_query_t *query)
Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
   _find_prefix ("type"),
   "mail"));
-   Xapian::Query string_query, final_query;
+   Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
  Xapian::QueryParser::FLAG_PHRASE |
@@ -469,7 +475,10 @@ notmuch_query_count_messages (notmuch_query_t *query)
 mail_query, string_query);
}

-   final_query = _notmuch_exclude_tags (query, final_query);
+   exclude_query = _notmuch_exclude_tags (query, final_query);
+
+   final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+final_query, exclude_query);

enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);
-- 
1.7.2.3



[PATCH v4 03/11] test: add tests for new cli --no-exclude option

2012-02-02 Thread Mark Walters
The tests test the new --no-exclude option to search and count.
There were no existing tests for the exclude behaviour for count so
added these too.
---
 test/count  |   21 +
 test/search |5 +
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/test/count b/test/count
index 300b171..976fff1 100755
--- a/test/count
+++ b/test/count
@@ -37,4 +37,25 @@ test_expect_equal \
 "0" \
 "`notmuch count --output=threads ${SEARCH}`"

+test_begin_subtest "count excluding \"deleted\" messages"
+notmuch config set search.exclude_tags = deleted
+generate_message '[subject]="Not deleted"'
+generate_message '[subject]="Another not deleted"'
+generate_message '[subject]="Deleted"'
+notmuch new > /dev/null
+notmuch tag +deleted id:$gen_msg_id
+test_expect_equal \
+"2" \
+"`notmuch count subject:deleted`"
+
+test_begin_subtest "count \"deleted\" messages, exclude overridden"
+test_expect_equal \
+"1" \
+"`notmuch count subject:deleted and tag:deleted`"
+
+test_begin_subtest "count \"deleted\" messages, with --no-exclude"
+test_expect_equal \
+"3" \
+"`notmuch count --no-exclude subject:deleted`"
+
 test_done
diff --git a/test/search b/test/search
index 414be35..3da5d17 100755
--- a/test/search
+++ b/test/search
@@ -148,6 +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 when --no-exclude 
specified"
+output=$(notmuch search --no-exclude 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_begin_subtest "Don't exclude \"deleted\" messages from search if not 
configured"
 notmuch config set search.exclude_tags
 output=$(notmuch search subject:deleted | notmuch_search_sanitize)
-- 
1.7.2.3



[PATCH v4 02/11] cli: Add --no-exclude to the man pages for search and count

2012-02-02 Thread Mark Walters
---
 man/man1/notmuch-count.1  |7 +++
 man/man1/notmuch-search.1 |7 +++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-count.1 b/man/man1/notmuch-count.1
index 25fe329..413b405 100644
--- a/man/man1/notmuch-count.1
+++ b/man/man1/notmuch-count.1
@@ -38,6 +38,13 @@ Output the number of matching messages. This is the default.
 Output the number of matching threads.
 .RE
 .RE
+
+.RS 4
+.TP 4
+.BR \-\-no\-exclude
+
+Do not exclude the messages matching search_exclude_tags in the config file.
+.RE
 .RE
 .RE

diff --git a/man/man1/notmuch-search.1 b/man/man1/notmuch-search.1
index 0bc3f40..bc54b4d 100644
--- a/man/man1/notmuch-search.1
+++ b/man/man1/notmuch-search.1
@@ -112,6 +112,13 @@ result from the end.
 Limit the number of displayed results to N.
 .RE

+.RS 4
+.TP 4
+.BR \-\-no\-exclude
+
+Do not exclude the messages matching search_exclude_tags in the config file.
+.RE
+
 .SH SEE ALSO

 \fBnotmuch\fR(1), \fBnotmuch-config\fR(1), \fBnotmuch-count\fR(1),
-- 
1.7.2.3



[PATCH v4 01/11] cli: add --no-exclude option to count and search.

2012-02-02 Thread Mark Walters
This option turns off the exclusion so all matching messages are
returned. We do not need to add this to notmuch-show as that does not
(yet) exclude.
---
 notmuch-count.c  |   17 +++--
 notmuch-search.c |   17 +++--
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 63459fb..5364507 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -35,8 +35,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 char *query_str;
 int opt_index;
 int output = OUTPUT_MESSAGES;
-const char **search_exclude_tags;
-size_t search_exclude_tags_length;
+notmuch_bool_t no_exclude = FALSE;
 unsigned int i;

 notmuch_opt_desc_t options[] = {
@@ -44,6 +43,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
  (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS },
  { "messages", OUTPUT_MESSAGES },
  { 0, 0 } } },
+   { NOTMUCH_OPT_BOOLEAN, &no_exclude, "no-exclude", 'd', 0 },
{ 0, 0, 0, 0, 0 }
 };

@@ -78,10 +78,15 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
return 1;
 }

-search_exclude_tags = notmuch_config_get_search_exclude_tags
-   (config, &search_exclude_tags_length);
-for (i = 0; i < search_exclude_tags_length; i++)
-   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+if (!no_exclude) {
+   const char **search_exclude_tags;
+   size_t search_exclude_tags_length;
+
+   search_exclude_tags = notmuch_config_get_search_exclude_tags
+   (config, &search_exclude_tags_length);
+   for (i = 0; i < search_exclude_tags_length; i++)
+   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+}

 switch (output) {
 case OUTPUT_MESSAGES:
diff --git a/notmuch-search.c b/notmuch-search.c
index d504051..43ec90b 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -423,8 +423,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 output_t output = OUTPUT_SUMMARY;
 int offset = 0;
 int limit = -1; /* unlimited */
-const char **search_exclude_tags;
-size_t search_exclude_tags_length;
+notmuch_bool_t no_exclude = FALSE;
 unsigned int i;

 enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT }
@@ -446,6 +445,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
  { "files", OUTPUT_FILES },
  { "tags", OUTPUT_TAGS },
  { 0, 0 } } },
+{ NOTMUCH_OPT_BOOLEAN, &no_exclude, "no-exclude", 'd', 0 },
{ NOTMUCH_OPT_INT, &offset, "offset", 'O', 0 },
{ NOTMUCH_OPT_INT, &limit, "limit", 'L', 0  },
{ 0, 0, 0, 0, 0 }
@@ -493,10 +493,15 @@ notmuch_search_command (void *ctx, int argc, char *argv[])

 notmuch_query_set_sort (query, sort);

-search_exclude_tags = notmuch_config_get_search_exclude_tags
-   (config, &search_exclude_tags_length);
-for (i = 0; i < search_exclude_tags_length; i++)
-   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+if (!no_exclude) {
+   const char **search_exclude_tags;
+   size_t search_exclude_tags_length;
+
+   search_exclude_tags = notmuch_config_get_search_exclude_tags
+   (config, &search_exclude_tags_length);
+   for (i = 0; i < search_exclude_tags_length; i++)
+   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+}

 switch (output) {
 default:
-- 
1.7.2.3



[Patch V4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag

2012-02-02 Thread Mark Walters

Here is the latest version of this patch set. I think I have fixed most
of the problems raised in review but there are some remaining issues
detailed below.

Changes and queries:

1) Changed --do-not-exclude option to --no-exclude

2) The api notmuch_query_set_omit_excluded_messages remains: without it I
can't see how a user can pass the notmuch_messages_t object around which
does not contain the excluded messages. See
id:"87fweusabh.fsf at qmul.ac.uk"

3) I have introduced a new function notmuch_thread_get_flag_messages
(notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)

which returns the number of messages with the specified flags on
flag_mask. (Note the current NOTMUCH_MESSAGE_FLAGs were nominally the
bit position of the flag rather than the actual bit of the flag. I
changed that. I am not completely happy with the style for this commit
(patch 7/11): any comments gratefully received!

4) In id:"20120131044352.GZ17991 at mit.edu" Austin suggested that I use a
notmuch_mset_messages_t object rather than an notmuch_doc_id_set_t. I
couldn't see how that would work unless the iterator would generate the
excludes in step with the main query. At the moment the doc_id object
just stores a bitmap listing all relevant excluded messages.

5) If we have a query which overrides the excludes such as "blah and
tag:deleted" should the tag:deleted messages still be marked excluded?
The current implementation does mark them excluded but my preference would
be not to. What do people think?

6) In id:"20120131050748.GA10844 at mit.edu" Austin pointed out that the
sort will be influenced by the excluded messages. I do not think either
of us are sure whether it should be or not so I have left it as is for
the moment.

Best wishes

Mark








[PATCH] test: make test_expect_equal_file() arguments flexible

2012-02-02 Thread Tomi Ollila
On Thu, 02 Feb 2012 14:33:56 +, David Edmondson  wrote:
> On Wed, 01 Feb 2012 09:24:32 -0800, Jameson Graef Rollins  finestructure.net> wrote:
> > If this is really a problem, I vote for 1.  In general, I am not in
> > favor of making the test suite more complicated than it needs to be.
> 
> After listening to the debate, I agree. The documentation should state
> that the order is 'expected actual' (or the other way around) and
> offenders should be shot on sight^W^W^Wfixed.

I've started to agree with Dmitry.

Why do something that computer can do -- to guide test writers to
give args in consistent order and provide suitable filenames.

Secondly as the output files are provided for human consumption
if there is consistent naming in expected output files helps 
developers getting parts of the big picture easier and finding 
right filenames easier.

... and the reviewers doesn't need to keep their plasma guns
handly.

Tomi



[PATCH] add support for user-specified files & directories to ignore

2012-02-02 Thread Tomi Ollila
A new configuration key 'new.ignore' is used to determine which
files and directories user wants not to be scanned as new mails.

Mark the corresponding test as no longer broken
(test from id:"1328105573-4626-1-git-send-email-pieter at praet.org" ).

This work merges my previous attempts and Andreas Amann's work
in id:"ylp7hi23mw8.fsf at tyndall.ie"

See notes in id:"20120202-new-ignore-1-git-send-email-too at iki.fi"
---

Whenever some already existing directory is added to the exclude list
and the parent directory timestamp has not changed, notmuch new will not
notice the directory has gone (as it still is there), user needs to 'touch'
the parent directory before next 'notmuch new' no make notmuch notice.

2012-01-26: could notmuch track mtime of the configuration file and if
that changes, ignore mail directory timestamps ?

See previous notes in id:"20120131-new-ignore-1-git-send-email-too at iki.fi"

 notmuch-client.h |   10 ++
 notmuch-config.c |   33 +++--
 notmuch-new.c|   45 +
 test/new |1 -
 4 files changed, 74 insertions(+), 15 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index e0eb594..26153df 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -245,11 +245,21 @@ notmuch_config_set_user_other_email (notmuch_config_t 
*config,
 const char **
 notmuch_config_get_new_tags (notmuch_config_t *config,
 size_t *length);
+
 void
 notmuch_config_set_new_tags (notmuch_config_t *config,
 const char *new_tags[],
 size_t length);

+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config,
+  size_t *length);
+
+void
+notmuch_config_set_new_ignore (notmuch_config_t *config,
+  const char *new_ignore[],
+  size_t length);
+
 notmuch_bool_t
 notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);

diff --git a/notmuch-config.c b/notmuch-config.c
index a124e34..1f01004 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -44,7 +44,10 @@ static const char new_config_comment[] =
 " The following options are supported here:\n"
 "\n"
 "\ttagsA list (separated by ';') of the tags that will be\n"
-"\tadded to all messages incorporated by \"notmuch new\".\n";
+"\tadded to all messages incorporated by \"notmuch new\".\n"
+"\n"
+"\tignore  A list (separated by ';') of file and directory names\n"
+"\tthat will not be searched for messages by \"notmuch new\".\n";

 static const char user_config_comment[] =
 " User configuration\n"
@@ -105,6 +108,8 @@ struct _notmuch_config {
 size_t user_other_email_length;
 const char **new_tags;
 size_t new_tags_length;
+const char **new_ignore;
+size_t new_ignore_length;
 notmuch_bool_t maildir_synchronize_flags;
 const char **search_exclude_tags;
 size_t search_exclude_tags_length;
@@ -264,6 +269,8 @@ notmuch_config_open (void *ctx,
 config->user_other_email_length = 0;
 config->new_tags = NULL;
 config->new_tags_length = 0;
+config->new_ignore = NULL;
+config->new_ignore_length = 0;
 config->maildir_synchronize_flags = TRUE;
 config->search_exclude_tags = NULL;
 config->search_exclude_tags_length = 0;
@@ -361,6 +368,10 @@ notmuch_config_open (void *ctx,
notmuch_config_set_new_tags (config, tags, 2);
 }

+if (notmuch_config_get_new_ignore (config, &tmp) == NULL) {
+   notmuch_config_set_new_ignore (config, NULL, 0);
+}
+
 if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) {
if (is_new) {
const char *tags[] = { "deleted", "spam" };
@@ -504,7 +515,8 @@ _config_set_list (notmuch_config_t *config,
  const char *list[],
  size_t length, const char ***config_var )
 {
-g_key_file_set_string_list (config->key_file, group, name, list, length);
+g_key_file_set_string_list (config->key_file,
+   group, name, list, length);
 talloc_free (*config_var);
 *config_var = NULL;
 }
@@ -609,6 +621,14 @@ notmuch_config_get_new_tags (notmuch_config_t *config,   
size_t *length)
 &(config->new_tags_length), length);
 }

+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config, size_t *length)
+{
+return _config_get_list (config, "new", "ignore",
+&(config->new_ignore),
+&(config->new_ignore_length), length);
+}

[PATCH v2] emacs: add default value to notmuch-search-line-faces

2012-02-02 Thread Jani Nikula
Add default value to notmuch-search-line-faces to show "unread"
messages in bold, and "flagged" messages in blue, to have some visual
indication of important messages in search results. This should be
helpful for new users.

"unread" tag is quite obvious, and handled specially both in the lib
and emacs ui. "flagged" is synced to maildir F flag in the lib. If one
syncs the maildir to IMAP, this also translates to corresponding IMAP
flag. (This is "starred" in GMail and Android.)

Signed-off-by: Jani Nikula 
---
 emacs/notmuch.el |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 5fa239a..bbf0aec 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -688,7 +688,8 @@ This function advances the next thread when finished."
  (goto-char (point-min))
  (forward-line (1- notmuch-search-target-line

-(defcustom notmuch-search-line-faces nil
+(defcustom notmuch-search-line-faces '(("unread" :weight bold)
+  ("flagged" :foreground "blue"))
   "Tag/face mapping for line highlighting in notmuch-search.

 Here is an example of how to color search results based on tags.
-- 
1.7.5.4



Re: [PATCH 1/2] test: add check for filename argument for test_expect_equal_file

2012-02-02 Thread Dmitry Kurochkin
Hi Jameson.

On Thu, 02 Feb 2012 10:00:59 -0800, Jameson Graef Rollins 
 wrote:
> Hey, Dmitry.  I'm so sorry I sent my last email on your original patch
> before I saw this new series.

No problems.

>  I do now like your original proposal
> better, since it shows the diff based the names the caller provides,
> which I now agree is probably the clearest and most robust solution.
> The second patch in this series could still go through, though, no
> matter what version of the change to test_expect_equal_file we go with.
> 

Ok.  I am going to wait for some time (e.g. 2 days) for more opinions.
Though, I doubt I would get any :) (And the problem is really minor, so
it probably does not deserve much attention.)

Currently, it seems that the original approach [1] wins.

Regards,
  Dmitry

[1] id:"1328080794-24670-1-git-send-email-dmitry.kuroch...@gmail.com"

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


Re: [PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Mark Walters
On Fri, 03 Feb 2012 01:07:59 +0200, Jani Nikula  wrote:
> On Thu, 02 Feb 2012 22:27:36 +, Mark Walters  
> wrote:
> > On Thu, 02 Feb 2012 23:55:33 +0200, Jani Nikula  wrote:
> > > 
> > > Hi Mark -
> > > 
> > > This is my first look at any version of the series; apologies if I'm
> > > clueless about some details... Please find some comments below.
> > > 
> > > BR,
> > > Jani.
> > > 
> > > 
> > > On Thu,  2 Feb 2012 17:43:35 +, Mark Walters 
> > >  wrote:
> > > > The function is
> > > > notmuch_thread_get_flag_messages
> > > > (notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)
> > > > 
> > > > and returns the number of messages with the specified flags on 
> > > > flag_mask.
> > > 
> > > Is the purpose of this function to get the count of messages that have
> > > certain flags set, certain flags not set, and certain flags don't-care?
> > 
> > Yes: I was trying to follow Austin's suggestion from
> > id:"20120124025331.gz16...@mit.edu" (although stupidly I didn't
> > follow his suggestion of a function name).
> > 
> > > At the very least, I think the documentation of the function should be
> > > greatly improved.
> > > 
> > > I think the name of the function should be notmuch_thread_count_messages
> > > which is like notmuch_query_count_messages, but for messages in threads
> > > (and with some extra restrictions).
> > 
> > Yes I like your name; before I change it do you (and others) prefer it
> > to Austin's suggestion of notmuch_thread_count_flags. Or we could even
> > be more verbose with something like
> > notmuch_thread_count_messages_with_flags
> 
> I'd like to make it clear that it's about message count. Not about
> getting flags, not about flag counts. _with_flags is a matter of taste,
> no strong opinions there.

I think I will go with notmuch_thread_count_messages as you suggest.

> > > >  /* Message flags */
> > > >  typedef enum _notmuch_message_flag {
> > > > -NOTMUCH_MESSAGE_FLAG_MATCH,
> > > > -NOTMUCH_MESSAGE_FLAG_EXCLUDED
> > > > +NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
> > > > +NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
> > > > +NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)
> > > 
> > > How are these used by the current lib users at the moment? How will they
> > > break with this change?

I will just comment on this: the *only* reason I put in
NOTMUCH_MESSAGE_FLAG_MAX was as a way of keeping track of the size of
the bitfield. If there is a better way do say!

> > The only existing flag is NOTMUCH_MESSAGE_FLAG_MATCH: that is currently
> > zero but in the current code that is the bit offset of the flag; in my
> > version it is the actual bit for the flag (otherwise I think flag masks
> > end up very ugly). I believe all callers use notmuch_message_set_flag
> > and notmuch_message_get_flag so they should not notice the difference.
> > 
> > > Please align the assignments. 
> > 
> > Will do.
> > 
> > > > @@ -457,8 +452,8 @@ _notmuch_thread_create (void *ctx,
> > > >  thread->message_hash = g_hash_table_new_full (g_str_hash, 
> > > > g_str_equal,
> > > >   free, NULL);
> > > >  
> > > > -thread->total_messages = 0;
> > > > -thread->matched_messages = 0;
> > > > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> > > > +   thread->flag_count_messages[i] = 0;
> > > 
> > > memset (thread->flag_count_messages, 0, 
> > > sizeof(thread->flag_count_messages));
> > 
> > 
> > Will do 
> > 
> > > >  thread->oldest = 0;
> > > >  thread->newest = 0;
> > > >  
> > > > @@ -473,6 +468,7 @@ _notmuch_thread_create (void *ctx,
> > > >  notmuch_messages_move_to_next (messages))
> > > >  {
> > > > unsigned int doc_id;
> > > > +   unsigned int message_flags;
> > > >  
> > > > message = notmuch_messages_get (messages);
> > > > doc_id = _notmuch_message_get_doc_id (message);
> > > > @@ -485,6 +481,10 @@ _notmuch_thread_create (void *ctx,
> > > > _notmuch_doc_id_set_remove (match_set, doc_id);
> > > > _thread_add_matched_message (thread, message, sort);
> > > > }
> > > > +   message_flags =
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH) |
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_EXCLUDED);
> > > > +   thread->flag_count_messages[message_flags]++;
> > > 
> > > The first impression of using a set of flags as index is that there's a
> > > bug. But this is to keep count of messages with certain flag sets rather
> > > than total for each flag, right? I think this needs more comments, more
> > > documentation. Already naming the field flag_set_message_counts or
> > > similar would help greatly.
> > 
> > I will try and document it better: on first reading I parsed your name
> > as flag set (as verb) message counts whereas I assume you mean "flag
> > set" as a noun! I will see if I can come up with something though.
> 
> Yes, as a noun! :)

I haven't come up wi

Re: [PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Mark Walters
On Fri, 03 Feb 2012 01:13:31 +0200, Jani Nikula  wrote:
> On Thu, 02 Feb 2012 22:35:10 +, Mark Walters  
> wrote:
> > 
> > On Fri, 03 Feb 2012 00:08:32 +0200, Jani Nikula  wrote:
> > > On Thu,  2 Feb 2012 17:43:36 +, Mark Walters 
> > >  wrote:
> > > > This adds the excludes to notmuch-show.c. We do not exclude when only
> > > > a single message (or part) is requested. notmuch-show will output the
> > > > exclude information when either text or json format is requested. As
> > > > this changes the output from notmuch-show it breaks many tests (in a
> > > > trivial and expected fashion).
> > > > ---
> > > >  notmuch-show.c |   24 
> > > >  1 files changed, 20 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/notmuch-show.c b/notmuch-show.c
> > > > index dec799c..108f13b 100644
> > > > --- a/notmuch-show.c
> > > > +++ b/notmuch-show.c
> > > > @@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, 
> > > > notmuch_message_t *message)
> > > >  static void
> > > >  format_message_text (unused (const void *ctx), notmuch_message_t 
> > > > *message, int indent)
> > > >  {
> > > > -printf ("id:%s depth:%d match:%d filename:%s\n",
> > > > +printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
> > > > notmuch_message_get_message_id (message),
> > > > indent,
> > > > -   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH),
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0,
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0,
> > > > notmuch_message_get_filename (message));
> > > >  }
> > > >  
> > > > @@ -212,9 +213,10 @@ format_message_json (const void *ctx, 
> > > > notmuch_message_t *message, unused (int in
> > > >  date = notmuch_message_get_date (message);
> > > >  relative_date = notmuch_time_relative_date (ctx, date);
> > > >  
> > > > -printf ("\"id\": %s, \"match\": %s, \"filename\": %s, 
> > > > \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
> > > > +printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, 
> > > > \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", 
> > > > \"tags\": [",
> > > > json_quote_str (ctx_quote, notmuch_message_get_message_id 
> > > > (message)),
> > > > notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false",
> > > > +   notmuch_message_get_flag (message, 
> > > > NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false",
> > > > json_quote_str (ctx_quote, notmuch_message_get_filename 
> > > > (message)),
> > > > date, relative_date);
> > > >  
> > > > @@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int 
> > > > argc), unused (char *argv[]))
> > > >  char *opt;
> > > >  const notmuch_show_format_t *format = &format_text;
> > > >  notmuch_show_params_t params;
> > > > +const char **search_exclude_tags;
> > > > +size_t search_exclude_tags_length;
> > > 
> > > Please move these within the if (!no_exclude) block.
> > 
> > Will do. (I forgot to move them in notmuch-show when doing notmuch-count
> > and notmuch-search)
> > 
> > > >  int mbox = 0;
> > > >  int format_specified = 0;
> > > >  int i;
> > > > +notmuch_bool_t no_exclude = FALSE;
> > > > +unsigned int j;
> > > 
> > > Same. Or better yet, reuse i.
> > 
> > Will do.
> > 
> > > >  params.entire_thread = 0;
> > > >  params.raw = 0;
> > > > @@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int 
> > > > argc), unused (char *argv[]))
> > > > params.part = atoi(argv[i] + sizeof ("--part=") - 1);
> > > > } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
> > > > params.entire_thread = 1;
> > > > +   } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
> > > > +   no_exclude = TRUE;
> > > > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
> > > >(STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
> > > > if (params.cryptoctx == NULL) {
> > > > @@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int 
> > > > argc), unused (char *argv[]))
> > > >  if (params.raw && params.part < 0)
> > > > params.part = 0;
> > > >  
> > > > +/* If a single message is requested we do not use search_excludes. 
> > > > */
> > > >  if (params.part >= 0)
> > > > return do_show_single (ctx, query, format, ¶ms);
> > > > -else
> > > > +else {
> > > 
> > > Nitpick: There's no rule about this, but I do like the style of using
> > > braces for both branches if either branch needs them.
> > 
> > Will fix.
> > 
> > > > +   if (!no_exclude) {
> > > > +   search_exclude_tags = notmuch_config_get_search_exclude_tags
> > > > +   (config, &search_exclude_tags_length);

Re: [PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Jani Nikula
On Thu, 02 Feb 2012 22:35:10 +, Mark Walters  
wrote:
> 
> On Fri, 03 Feb 2012 00:08:32 +0200, Jani Nikula  wrote:
> > On Thu,  2 Feb 2012 17:43:36 +, Mark Walters 
> >  wrote:
> > > This adds the excludes to notmuch-show.c. We do not exclude when only
> > > a single message (or part) is requested. notmuch-show will output the
> > > exclude information when either text or json format is requested. As
> > > this changes the output from notmuch-show it breaks many tests (in a
> > > trivial and expected fashion).
> > > ---
> > >  notmuch-show.c |   24 
> > >  1 files changed, 20 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/notmuch-show.c b/notmuch-show.c
> > > index dec799c..108f13b 100644
> > > --- a/notmuch-show.c
> > > +++ b/notmuch-show.c
> > > @@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, 
> > > notmuch_message_t *message)
> > >  static void
> > >  format_message_text (unused (const void *ctx), notmuch_message_t 
> > > *message, int indent)
> > >  {
> > > -printf ("id:%s depth:%d match:%d filename:%s\n",
> > > +printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
> > >   notmuch_message_get_message_id (message),
> > >   indent,
> > > - notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
> > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 
> > > : 0,
> > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> > > 1 : 0,
> > >   notmuch_message_get_filename (message));
> > >  }
> > >  
> > > @@ -212,9 +213,10 @@ format_message_json (const void *ctx, 
> > > notmuch_message_t *message, unused (int in
> > >  date = notmuch_message_get_date (message);
> > >  relative_date = notmuch_time_relative_date (ctx, date);
> > >  
> > > -printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": 
> > > %ld, \"date_relative\": \"%s\", \"tags\": [",
> > > +printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": 
> > > %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
> > >   json_quote_str (ctx_quote, notmuch_message_get_message_id 
> > > (message)),
> > >   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 
> > > "true" : "false",
> > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> > > "true" : "false",
> > >   json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
> > >   date, relative_date);
> > >  
> > > @@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int 
> > > argc), unused (char *argv[]))
> > >  char *opt;
> > >  const notmuch_show_format_t *format = &format_text;
> > >  notmuch_show_params_t params;
> > > +const char **search_exclude_tags;
> > > +size_t search_exclude_tags_length;
> > 
> > Please move these within the if (!no_exclude) block.
> 
> Will do. (I forgot to move them in notmuch-show when doing notmuch-count
> and notmuch-search)
> 
> > >  int mbox = 0;
> > >  int format_specified = 0;
> > >  int i;
> > > +notmuch_bool_t no_exclude = FALSE;
> > > +unsigned int j;
> > 
> > Same. Or better yet, reuse i.
> 
> Will do.
> 
> > >  params.entire_thread = 0;
> > >  params.raw = 0;
> > > @@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > > unused (char *argv[]))
> > >   params.part = atoi(argv[i] + sizeof ("--part=") - 1);
> > >   } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
> > >   params.entire_thread = 1;
> > > + } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
> > > + no_exclude = TRUE;
> > >   } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
> > >  (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
> > >   if (params.cryptoctx == NULL) {
> > > @@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int 
> > > argc), unused (char *argv[]))
> > >  if (params.raw && params.part < 0)
> > >   params.part = 0;
> > >  
> > > +/* If a single message is requested we do not use search_excludes. */
> > >  if (params.part >= 0)
> > >   return do_show_single (ctx, query, format, ¶ms);
> > > -else
> > > +else {
> > 
> > Nitpick: There's no rule about this, but I do like the style of using
> > braces for both branches if either branch needs them.
> 
> Will fix.
> 
> > > + if (!no_exclude) {
> > > + search_exclude_tags = notmuch_config_get_search_exclude_tags
> > > + (config, &search_exclude_tags_length);
> > > + for (j = 0; j < search_exclude_tags_length; j++)
> > > + notmuch_query_add_tag_exclude (query, search_exclude_tags[j]);
> > > + }
> > >   return do_show (ctx, query, format, ¶ms);
> > > +}
> > 
> > Hmm, unreachable code below. Why doesn't the compiler complain?
> 
> Yes I wondered about that (id:"20120120171801.ga16...@mit.edu"): but didn't 
> think I should do anything about
> that in this series.

I'll send patches to fix th

Re: [PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Jani Nikula
On Thu, 02 Feb 2012 22:27:36 +, Mark Walters  
wrote:
> On Thu, 02 Feb 2012 23:55:33 +0200, Jani Nikula  wrote:
> > 
> > Hi Mark -
> > 
> > This is my first look at any version of the series; apologies if I'm
> > clueless about some details... Please find some comments below.
> > 
> > BR,
> > Jani.
> > 
> > 
> > On Thu,  2 Feb 2012 17:43:35 +, Mark Walters 
> >  wrote:
> > > The function is
> > > notmuch_thread_get_flag_messages
> > > (notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)
> > > 
> > > and returns the number of messages with the specified flags on flag_mask.
> > 
> > Is the purpose of this function to get the count of messages that have
> > certain flags set, certain flags not set, and certain flags don't-care?
> 
> Yes: I was trying to follow Austin's suggestion from
> id:"20120124025331.gz16...@mit.edu" (although stupidly I didn't
> follow his suggestion of a function name).
> 
> > At the very least, I think the documentation of the function should be
> > greatly improved.
> > 
> > I think the name of the function should be notmuch_thread_count_messages
> > which is like notmuch_query_count_messages, but for messages in threads
> > (and with some extra restrictions).
> 
> Yes I like your name; before I change it do you (and others) prefer it
> to Austin's suggestion of notmuch_thread_count_flags. Or we could even
> be more verbose with something like
> notmuch_thread_count_messages_with_flags

I'd like to make it clear that it's about message count. Not about
getting flags, not about flag counts. _with_flags is a matter of taste,
no strong opinions there.

> 
> > >  /* Message flags */
> > >  typedef enum _notmuch_message_flag {
> > > -NOTMUCH_MESSAGE_FLAG_MATCH,
> > > -NOTMUCH_MESSAGE_FLAG_EXCLUDED
> > > +NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
> > > +NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
> > > +NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)
> > 
> > How are these used by the current lib users at the moment? How will they
> > break with this change?
> 
> The only existing flag is NOTMUCH_MESSAGE_FLAG_MATCH: that is currently
> zero but in the current code that is the bit offset of the flag; in my
> version it is the actual bit for the flag (otherwise I think flag masks
> end up very ugly). I believe all callers use notmuch_message_set_flag
> and notmuch_message_get_flag so they should not notice the difference.
> 
> > Please align the assignments. 
> 
> Will do.
> 
> > > @@ -457,8 +452,8 @@ _notmuch_thread_create (void *ctx,
> > >  thread->message_hash = g_hash_table_new_full (g_str_hash, 
> > > g_str_equal,
> > > free, NULL);
> > >  
> > > -thread->total_messages = 0;
> > > -thread->matched_messages = 0;
> > > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> > > + thread->flag_count_messages[i] = 0;
> > 
> > memset (thread->flag_count_messages, 0, 
> > sizeof(thread->flag_count_messages));
> 
> 
> Will do 
> 
> > >  thread->oldest = 0;
> > >  thread->newest = 0;
> > >  
> > > @@ -473,6 +468,7 @@ _notmuch_thread_create (void *ctx,
> > >notmuch_messages_move_to_next (messages))
> > >  {
> > >   unsigned int doc_id;
> > > + unsigned int message_flags;
> > >  
> > >   message = notmuch_messages_get (messages);
> > >   doc_id = _notmuch_message_get_doc_id (message);
> > > @@ -485,6 +481,10 @@ _notmuch_thread_create (void *ctx,
> > >   _notmuch_doc_id_set_remove (match_set, doc_id);
> > >   _thread_add_matched_message (thread, message, sort);
> > >   }
> > > + message_flags =
> > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) |
> > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED);
> > > + thread->flag_count_messages[message_flags]++;
> > 
> > The first impression of using a set of flags as index is that there's a
> > bug. But this is to keep count of messages with certain flag sets rather
> > than total for each flag, right? I think this needs more comments, more
> > documentation. Already naming the field flag_set_message_counts or
> > similar would help greatly.
> 
> I will try and document it better: on first reading I parsed your name
> as flag set (as verb) message counts whereas I assume you mean "flag
> set" as a noun! I will see if I can come up with something though.

Yes, as a noun! :)

> 
> > >   _notmuch_message_close (message);
> > >  }
> > > @@ -511,15 +511,28 @@ notmuch_thread_get_thread_id (notmuch_thread_t 
> > > *thread)
> > >  }
> > >  
> > >  int
> > > +notmuch_thread_get_flag_messages (notmuch_thread_t *thread, unsigned int 
> > > flag_mask, unsigned int flags)
> > > +{
> > > +unsigned int i;
> > > +int count = 0;
> > > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> > 
> > ARRAY_SIZE (thread->flag_count_messages)
> 
> ok
> 
> > 
> > > + if ((i & flag_mask) == (flags & flag_mask))
> > > + count += thread->flag_count_messages[i];
> > > +return count;
> > > +}
> > 
> > I wonder if the s

BiDi

2012-02-02 Thread James Vasile
On Thu, 02 Feb 2012 09:44:07 -0800, Jameson Graef Rollins  wrote:
> On Tue, 24 Jan 2012 20:08:14 +, Clint Adams  wrote:
> > I just received an email in RTL script and it was rendered incorrectly
> > in the emacs interface.  Does anyone know what to do about this?
> 
> More info please.  What is "RTL script"?  Is that "right to left"?  If
> so, yikes.  I can't even imagine what a mess that would have looked
> like.  Another argument against this crazy indenting stuff we do.  I
> hope the thread was also indenting from the right!
> 
> jamie.
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

Is anybody interested in a more mutt-like single-email view with a
threaded index?  No indenting, no waiting forever for long threads to
fontify, no wading through a long thread looking for the one email you
actually want.


Re: [PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Mark Walters

On Fri, 03 Feb 2012 00:08:32 +0200, Jani Nikula  wrote:
> On Thu,  2 Feb 2012 17:43:36 +, Mark Walters  
> wrote:
> > This adds the excludes to notmuch-show.c. We do not exclude when only
> > a single message (or part) is requested. notmuch-show will output the
> > exclude information when either text or json format is requested. As
> > this changes the output from notmuch-show it breaks many tests (in a
> > trivial and expected fashion).
> > ---
> >  notmuch-show.c |   24 
> >  1 files changed, 20 insertions(+), 4 deletions(-)
> > 
> > diff --git a/notmuch-show.c b/notmuch-show.c
> > index dec799c..108f13b 100644
> > --- a/notmuch-show.c
> > +++ b/notmuch-show.c
> > @@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, 
> > notmuch_message_t *message)
> >  static void
> >  format_message_text (unused (const void *ctx), notmuch_message_t *message, 
> > int indent)
> >  {
> > -printf ("id:%s depth:%d match:%d filename:%s\n",
> > +printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
> > notmuch_message_get_message_id (message),
> > indent,
> > -   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 
> > : 0,
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> > 1 : 0,
> > notmuch_message_get_filename (message));
> >  }
> >  
> > @@ -212,9 +213,10 @@ format_message_json (const void *ctx, 
> > notmuch_message_t *message, unused (int in
> >  date = notmuch_message_get_date (message);
> >  relative_date = notmuch_time_relative_date (ctx, date);
> >  
> > -printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": 
> > %ld, \"date_relative\": \"%s\", \"tags\": [",
> > +printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": 
> > %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
> > json_quote_str (ctx_quote, notmuch_message_get_message_id 
> > (message)),
> > notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 
> > "true" : "false",
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> > "true" : "false",
> > json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
> > date, relative_date);
> >  
> > @@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> >  char *opt;
> >  const notmuch_show_format_t *format = &format_text;
> >  notmuch_show_params_t params;
> > +const char **search_exclude_tags;
> > +size_t search_exclude_tags_length;
> 
> Please move these within the if (!no_exclude) block.

Will do. (I forgot to move them in notmuch-show when doing notmuch-count
and notmuch-search)

> >  int mbox = 0;
> >  int format_specified = 0;
> >  int i;
> > +notmuch_bool_t no_exclude = FALSE;
> > +unsigned int j;
> 
> Same. Or better yet, reuse i.

Will do.

> >  params.entire_thread = 0;
> >  params.raw = 0;
> > @@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> > params.part = atoi(argv[i] + sizeof ("--part=") - 1);
> > } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
> > params.entire_thread = 1;
> > +   } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
> > +   no_exclude = TRUE;
> > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
> >(STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
> > if (params.cryptoctx == NULL) {
> > @@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> >  if (params.raw && params.part < 0)
> > params.part = 0;
> >  
> > +/* If a single message is requested we do not use search_excludes. */
> >  if (params.part >= 0)
> > return do_show_single (ctx, query, format, ¶ms);
> > -else
> > +else {
> 
> Nitpick: There's no rule about this, but I do like the style of using
> braces for both branches if either branch needs them.

Will fix.

> > +   if (!no_exclude) {
> > +   search_exclude_tags = notmuch_config_get_search_exclude_tags
> > +   (config, &search_exclude_tags_length);
> > +   for (j = 0; j < search_exclude_tags_length; j++)
> > +   notmuch_query_add_tag_exclude (query, search_exclude_tags[j]);
> > +   }
> > return do_show (ctx, query, format, ¶ms);
> > +}
> 
> Hmm, unreachable code below. Why doesn't the compiler complain?

Yes I wondered about that (id:"20120120171801.ga16...@mit.edu"): but didn't 
think I should do anything about
that in this series.

Thanks

Mark

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


[PATCH] test: make test_expect_equal_file() arguments flexible

2012-02-02 Thread David Edmondson
On Wed, 01 Feb 2012 09:24:32 -0800, Jameson Graef Rollins  wrote:
> If this is really a problem, I vote for 1.  In general, I am not in
> favor of making the test suite more complicated than it needs to be.

After listening to the debate, I agree. The documentation should state
that the order is 'expected actual' (or the other way around) and
offenders should be shot on sight^W^W^Wfixed.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120202/9b53e36a/attachment.pgp>


Re: [PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Mark Walters
On Thu, 02 Feb 2012 23:55:33 +0200, Jani Nikula  wrote:
> 
> Hi Mark -
> 
> This is my first look at any version of the series; apologies if I'm
> clueless about some details... Please find some comments below.
> 
> BR,
> Jani.
> 
> 
> On Thu,  2 Feb 2012 17:43:35 +, Mark Walters  
> wrote:
> > The function is
> > notmuch_thread_get_flag_messages
> > (notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)
> > 
> > and returns the number of messages with the specified flags on flag_mask.
> 
> Is the purpose of this function to get the count of messages that have
> certain flags set, certain flags not set, and certain flags don't-care?

Yes: I was trying to follow Austin's suggestion from
id:"20120124025331.gz16...@mit.edu" (although stupidly I didn't
follow his suggestion of a function name).

> At the very least, I think the documentation of the function should be
> greatly improved.
> 
> I think the name of the function should be notmuch_thread_count_messages
> which is like notmuch_query_count_messages, but for messages in threads
> (and with some extra restrictions).

Yes I like your name; before I change it do you (and others) prefer it
to Austin's suggestion of notmuch_thread_count_flags. Or we could even
be more verbose with something like
notmuch_thread_count_messages_with_flags

> >  /* Message flags */
> >  typedef enum _notmuch_message_flag {
> > -NOTMUCH_MESSAGE_FLAG_MATCH,
> > -NOTMUCH_MESSAGE_FLAG_EXCLUDED
> > +NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
> > +NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
> > +NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)
> 
> How are these used by the current lib users at the moment? How will they
> break with this change?

The only existing flag is NOTMUCH_MESSAGE_FLAG_MATCH: that is currently
zero but in the current code that is the bit offset of the flag; in my
version it is the actual bit for the flag (otherwise I think flag masks
end up very ugly). I believe all callers use notmuch_message_set_flag
and notmuch_message_get_flag so they should not notice the difference.

> Please align the assignments. 

Will do.

> > @@ -457,8 +452,8 @@ _notmuch_thread_create (void *ctx,
> >  thread->message_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
> >   free, NULL);
> >  
> > -thread->total_messages = 0;
> > -thread->matched_messages = 0;
> > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> > +   thread->flag_count_messages[i] = 0;
> 
> memset (thread->flag_count_messages, 0, sizeof(thread->flag_count_messages));


Will do 

> >  thread->oldest = 0;
> >  thread->newest = 0;
> >  
> > @@ -473,6 +468,7 @@ _notmuch_thread_create (void *ctx,
> >  notmuch_messages_move_to_next (messages))
> >  {
> > unsigned int doc_id;
> > +   unsigned int message_flags;
> >  
> > message = notmuch_messages_get (messages);
> > doc_id = _notmuch_message_get_doc_id (message);
> > @@ -485,6 +481,10 @@ _notmuch_thread_create (void *ctx,
> > _notmuch_doc_id_set_remove (match_set, doc_id);
> > _thread_add_matched_message (thread, message, sort);
> > }
> > +   message_flags =
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) |
> > +   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED);
> > +   thread->flag_count_messages[message_flags]++;
> 
> The first impression of using a set of flags as index is that there's a
> bug. But this is to keep count of messages with certain flag sets rather
> than total for each flag, right? I think this needs more comments, more
> documentation. Already naming the field flag_set_message_counts or
> similar would help greatly.

I will try and document it better: on first reading I parsed your name
as flag set (as verb) message counts whereas I assume you mean "flag
set" as a noun! I will see if I can come up with something though.

> > _notmuch_message_close (message);
> >  }
> > @@ -511,15 +511,28 @@ notmuch_thread_get_thread_id (notmuch_thread_t 
> > *thread)
> >  }
> >  
> >  int
> > +notmuch_thread_get_flag_messages (notmuch_thread_t *thread, unsigned int 
> > flag_mask, unsigned int flags)
> > +{
> > +unsigned int i;
> > +int count = 0;
> > +for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
> 
> ARRAY_SIZE (thread->flag_count_messages)

ok

> 
> > +   if ((i & flag_mask) == (flags & flag_mask))
> > +   count += thread->flag_count_messages[i];
> > +return count;
> > +}
> 
> I wonder if the same could be accomplished by using two flag mask
> parameters, include_flag_mask and exclude_flag_mask. I'm thinking of the
> usage, would it be easier to use:
> 
> notmuch_query_count_messages (thread, NOTMUCH_MESSAGE_FLAG_MATCH, 
> NOTMUCH_MESSAGE_FLAG_EXCLUDED);
> 
> to get number of messages that have MATCH but not EXCLUDED? 0 as
> include_flag_mask could still be special for "all", and you could use:
> 
> notmuch_query_count_messages (thread, 0, NOTMUCH_MESSAGE_FLAG_EXCL

Re: [PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Jani Nikula
On Thu,  2 Feb 2012 17:43:36 +, Mark Walters  
wrote:
> This adds the excludes to notmuch-show.c. We do not exclude when only
> a single message (or part) is requested. notmuch-show will output the
> exclude information when either text or json format is requested. As
> this changes the output from notmuch-show it breaks many tests (in a
> trivial and expected fashion).
> ---
>  notmuch-show.c |   24 
>  1 files changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/notmuch-show.c b/notmuch-show.c
> index dec799c..108f13b 100644
> --- a/notmuch-show.c
> +++ b/notmuch-show.c
> @@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, 
> notmuch_message_t *message)
>  static void
>  format_message_text (unused (const void *ctx), notmuch_message_t *message, 
> int indent)
>  {
> -printf ("id:%s depth:%d match:%d filename:%s\n",
> +printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
>   notmuch_message_get_message_id (message),
>   indent,
> - notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
> + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 
> : 0,
> + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> 1 : 0,
>   notmuch_message_get_filename (message));
>  }
>  
> @@ -212,9 +213,10 @@ format_message_json (const void *ctx, notmuch_message_t 
> *message, unused (int in
>  date = notmuch_message_get_date (message);
>  relative_date = notmuch_time_relative_date (ctx, date);
>  
> -printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": 
> %ld, \"date_relative\": \"%s\", \"tags\": [",
> +printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, 
> \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
>   json_quote_str (ctx_quote, notmuch_message_get_message_id 
> (message)),
>   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 
> "true" : "false",
> + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
> "true" : "false",
>   json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
>   date, relative_date);
>  
> @@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int argc), 
> unused (char *argv[]))
>  char *opt;
>  const notmuch_show_format_t *format = &format_text;
>  notmuch_show_params_t params;
> +const char **search_exclude_tags;
> +size_t search_exclude_tags_length;

Please move these within the if (!no_exclude) block.

>  int mbox = 0;
>  int format_specified = 0;
>  int i;
> +notmuch_bool_t no_exclude = FALSE;
> +unsigned int j;

Same. Or better yet, reuse i.

>  
>  params.entire_thread = 0;
>  params.raw = 0;
> @@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int argc), 
> unused (char *argv[]))
>   params.part = atoi(argv[i] + sizeof ("--part=") - 1);
>   } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
>   params.entire_thread = 1;
> + } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
> + no_exclude = TRUE;
>   } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
>  (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
>   if (params.cryptoctx == NULL) {
> @@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int argc), 
> unused (char *argv[]))
>  if (params.raw && params.part < 0)
>   params.part = 0;
>  
> +/* If a single message is requested we do not use search_excludes. */
>  if (params.part >= 0)
>   return do_show_single (ctx, query, format, ¶ms);
> -else
> +else {

Nitpick: There's no rule about this, but I do like the style of using
braces for both branches if either branch needs them.

> + if (!no_exclude) {
> + search_exclude_tags = notmuch_config_get_search_exclude_tags
> + (config, &search_exclude_tags_length);
> + for (j = 0; j < search_exclude_tags_length; j++)
> + notmuch_query_add_tag_exclude (query, search_exclude_tags[j]);
> + }
>   return do_show (ctx, query, format, ¶ms);
> +}

Hmm, unreachable code below. Why doesn't the compiler complain?

>  
>  notmuch_query_destroy (query);
>  notmuch_database_close (notmuch);
> -- 
> 1.7.2.3
> 
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Jani Nikula

Hi Mark -

This is my first look at any version of the series; apologies if I'm
clueless about some details... Please find some comments below.

BR,
Jani.


On Thu,  2 Feb 2012 17:43:35 +, Mark Walters  
wrote:
> The function is
> notmuch_thread_get_flag_messages
> (notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)
> 
> and returns the number of messages with the specified flags on flag_mask.

Is the purpose of this function to get the count of messages that have
certain flags set, certain flags not set, and certain flags don't-care?

At the very least, I think the documentation of the function should be
greatly improved.

I think the name of the function should be notmuch_thread_count_messages
which is like notmuch_query_count_messages, but for messages in threads
(and with some extra restrictions).

> 
> This generalises the existing function
> notmuch_thread_get_total_messages and
> notmuch_thread_get_matched_messages which are retained to maintain
> compatibility.
> ---
>  lib/message.cc |6 +++---
>  lib/notmuch.h  |   15 +--
>  lib/thread.cc  |   39 ++-
>  3 files changed, 42 insertions(+), 18 deletions(-)
> 
> diff --git a/lib/message.cc b/lib/message.cc
> index 0075425..d60da83 100644
> --- a/lib/message.cc
> +++ b/lib/message.cc
> @@ -746,7 +746,7 @@ notmuch_bool_t
>  notmuch_message_get_flag (notmuch_message_t *message,
> notmuch_message_flag_t flag)
>  {
> -return message->flags & (1 << flag);
> +return message->flags & flag;
>  }
>  
>  void
> @@ -754,9 +754,9 @@ notmuch_message_set_flag (notmuch_message_t *message,
> notmuch_message_flag_t flag, notmuch_bool_t enable)
>  {
>  if (enable)
> - message->flags |= (1 << flag);
> + message->flags |= flag;
>  else
> - message->flags &= ~(1 << flag);
> + message->flags &= ~flag;
>  }
>  
>  time_t
> diff --git a/lib/notmuch.h b/lib/notmuch.h
> index f75afae..c02e7f4 100644
> --- a/lib/notmuch.h
> +++ b/lib/notmuch.h
> @@ -654,6 +654,16 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread);
>  int
>  notmuch_thread_get_total_messages (notmuch_thread_t *thread);
>  
> +/* Get the number of messages in 'thread' which have the specified
> + * flags on flag_mask.
> + *
> + * This is a more general interface than
> + * notmuch_thread_get_total_messages or
> + * notmuch_thread_get_matched_messages
> + */
> +int
> +notmuch_thread_get_flag_messages (notmuch_thread_t *thread, unsigned int 
> flag_mask, unsigned int flags);
> +
>  /* Get a notmuch_messages_t iterator for the top-level messages in
>   * 'thread'.
>   *
> @@ -902,8 +912,9 @@ notmuch_message_get_filenames (notmuch_message_t 
> *message);
>  
>  /* Message flags */
>  typedef enum _notmuch_message_flag {
> -NOTMUCH_MESSAGE_FLAG_MATCH,
> -NOTMUCH_MESSAGE_FLAG_EXCLUDED
> +NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
> +NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
> +NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)

How are these used by the current lib users at the moment? How will they
break with this change?

Please align the assignments. 

>  } notmuch_message_flag_t;
>  
>  /* Get a value of a flag for the email corresponding to 'message'. */
> diff --git a/lib/thread.cc b/lib/thread.cc
> index e976d64..542f7f4 100644
> --- a/lib/thread.cc
> +++ b/lib/thread.cc
> @@ -37,8 +37,7 @@ struct visible _notmuch_thread {
>  
>  notmuch_message_list_t *message_list;
>  GHashTable *message_hash;
> -int total_messages;
> -int matched_messages;
> +int flag_count_messages[NOTMUCH_MESSAGE_FLAG_MAX];
>  time_t oldest;
>  time_t newest;
>  };
> @@ -226,7 +225,6 @@ _thread_add_message (notmuch_thread_t *thread,
>  
>  _notmuch_message_list_add_message (thread->message_list,
>  talloc_steal (thread, message));
> -thread->total_messages++;
>  
>  g_hash_table_insert (thread->message_hash,
>xstrdup (notmuch_message_get_message_id (message)),
> @@ -319,21 +317,18 @@ _thread_add_matched_message (notmuch_thread_t *thread,
>  
>  date = notmuch_message_get_date (message);
>  
> -if (date < thread->oldest || ! thread->matched_messages) {
> +if (date < thread->oldest || ! notmuch_thread_get_matched_messages 
> (thread)) {
>   thread->oldest = date;
>   if (sort == NOTMUCH_SORT_OLDEST_FIRST)
>   _thread_set_subject_from_message (thread, message);
>  }
>  
> -if (date > thread->newest || ! thread->matched_messages) {
> +if (date > thread->newest || ! notmuch_thread_get_matched_messages 
> (thread)) {
>   thread->newest = date;
>   if (sort != NOTMUCH_SORT_OLDEST_FIRST)
>   _thread_set_subject_from_message (thread, message);
>  }
>  
> -if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
> - thread->matched_messages++;
> -
>  if (g_hash_table_lookup_extended (thread->message_hash,
>

Re: BiDi

2012-02-02 Thread James Vasile
On Thu, 02 Feb 2012 09:44:07 -0800, Jameson Graef Rollins 
 wrote:
> On Tue, 24 Jan 2012 20:08:14 +, Clint Adams  wrote:
> > I just received an email in RTL script and it was rendered incorrectly
> > in the emacs interface.  Does anyone know what to do about this?
> 
> More info please.  What is "RTL script"?  Is that "right to left"?  If
> so, yikes.  I can't even imagine what a mess that would have looked
> like.  Another argument against this crazy indenting stuff we do.  I
> hope the thread was also indenting from the right!
> 
> jamie.
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

Is anybody interested in a more mutt-like single-email view with a
threaded index?  No indenting, no waiting forever for long threads to
fontify, no wading through a long thread looking for the one email you
actually want.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v6 8/8] emacs: A prefix argument to `notmuch-show' should invert the matching message behaviour.

2012-02-02 Thread David Edmondson
Allow the user to open a thread with inverted
`notmuch-show-only-matching-messages' behaviour using a prefix
argument.
---
 emacs/notmuch-show.el |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index ae7af02..e9aa4e7 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1024,8 +1024,11 @@ function is used."
 ;; buffer.
 (setq notmuch-show-process-crypto notmuch-crypto-process-mime)
 ;; Set the default value for
-;; `notmuch-show-elide-non-matching-messages' in this buffer.
+;; `notmuch-show-elide-non-matching-messages' in this buffer. If
+;; there is a prefix argument, invert the default.
 (setq notmuch-show-elide-non-matching-messages 
notmuch-show-only-matching-messages)
+(if current-prefix-arg
+   (setq notmuch-show-elide-non-matching-messages (not 
notmuch-show-elide-non-matching-messages)))

 (setq notmuch-show-thread-id thread-id
  notmuch-show-parent-buffer parent-buffer
-- 
1.7.8.3



[PATCH v6 7/8] emacs: Add `notmuch-show-only-matching-messages'.

2012-02-02 Thread David Edmondson
Allow the user to choose that only matching messages are shown by
default.
---
 emacs/notmuch-show.el |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 895feb5..ae7af02 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -125,6 +125,11 @@ indentation."
 (const :tag "View interactively"
notmuch-show-interactively-view-part)))

+(defcustom notmuch-show-only-matching-messages nil
+  "Only matching messages are shown by default."
+  :type 'boolean
+  :group 'notmuch-show)
+
 (defvar notmuch-show-thread-id nil)
 (make-variable-buffer-local 'notmuch-show-thread-id)
 (put 'notmuch-show-thread-id 'permanent-local t)
@@ -1018,6 +1023,9 @@ function is used."
 ;; Set the default value for `notmuch-show-process-crypto' in this
 ;; buffer.
 (setq notmuch-show-process-crypto notmuch-crypto-process-mime)
+;; Set the default value for
+;; `notmuch-show-elide-non-matching-messages' in this buffer.
+(setq notmuch-show-elide-non-matching-messages 
notmuch-show-only-matching-messages)

 (setq notmuch-show-thread-id thread-id
  notmuch-show-parent-buffer parent-buffer
-- 
1.7.8.3



[PATCH v6 6/8] emacs: Check that the parent buffer is alive before using it.

2012-02-02 Thread David Edmondson
---
 emacs/notmuch-show.el |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 1b31166..895feb5 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1671,7 +1671,7 @@ added."
   (interactive "P")
   (let ((parent-buffer notmuch-show-parent-buffer))
 (notmuch-kill-this-buffer)
-(when parent-buffer
+(when (buffer-live-p parent-buffer)
   (switch-to-buffer parent-buffer)
   (notmuch-search-next-thread)
   (if show-next
-- 
1.7.8.3



[PATCH v6 5/8] emacs: Optionally retain the state of the buffer during `notmuch-show-refresh-view'.

2012-02-02 Thread David Edmondson
With an argument, record and reply the state of the buffer during
`notmuch-show-refresh-view'.

In this context, "state" is defined as:
 - the open/closed state of each message,
 - the current message.

Traditional use of refresh with the = key does not retain the
state. The recently introduced toggle commands ($, !, < and >) do
retain the state.
---
 emacs/notmuch-show.el |   56 ++---
 1 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 8d318c9..1b31166 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -938,7 +938,7 @@ current buffer, if possible."
   (message (if notmuch-show-process-crypto
   "Processing cryptographic MIME parts."
 "Not processing cryptographic MIME parts."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))

 (defun notmuch-show-toggle-elide-non-matching ()
   "Toggle the display of non-matching messages."
@@ -947,7 +947,7 @@ current buffer, if possible."
   (message (if notmuch-show-elide-non-matching-messages
   "Showing matching messages only."
 "Showing all messages."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))

 (defun notmuch-show-toggle-thread-indentation ()
   "Toggle the indentation of threads."
@@ -956,7 +956,7 @@ current buffer, if possible."
   (message (if notmuch-show-indent-content
   "Content is indented."
 "Content is not indented."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))

 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
@@ -1060,14 +1060,54 @@ function is used."

 (notmuch-show-mark-read)))

-(defun notmuch-show-refresh-view ()
+(defun notmuch-show-capture-state ()
+  "Capture the state of the current buffer.
+
+This includes:
+ - the list of open messages,
+ - the current message."
+  (list (notmuch-show-get-message-id) 
(notmuch-show-get-message-ids-for-open-messages)))
+
+(defun notmuch-show-apply-state (state)
+  "Apply STATE to the current buffer.
+
+This includes:
+ - opening the messages previously opened,
+ - closing all other messages,
+ - moving to the correct current message."
+  (let ((current (car state))
+   (open (cadr state)))
+
+;; Open those that were open.
+(goto-char (point-min))
+(loop do (notmuch-show-message-visible 
(notmuch-show-get-message-properties)
+  (member 
(notmuch-show-get-message-id) open))
+ until (not (notmuch-show-goto-message-next)))
+
+;; Go to the previously open message.
+(goto-char (point-min))
+(unless (loop if (string= current (notmuch-show-get-message-id))
+ return t
+ until (not (notmuch-show-goto-message-next)))
+  (goto-char (point-min))
+  (message "Previously current message not found."))
+(notmuch-show-message-adjust)))
+
+(defun notmuch-show-refresh-view (&optional retain-state)
   "Refresh the current view.

-Refreshes the current view, observing changes in cryptographic preferences."
+Refreshes the current view, observing changes in display
+preferences. If RETAIN-STATE is non-nil then the state of the
+buffer is stored and re-applied after the refresh."
   (interactive)
-  (let ((inhibit-read-only t))
-(erase-buffer))
-  (notmuch-show-worker))
+  (let ((inhibit-read-only t)
+   state)
+(if retain-state
+   (setq state (notmuch-show-capture-state)))
+(erase-buffer)
+(notmuch-show-worker)
+(if state
+   (notmuch-show-apply-state state

 (defvar notmuch-show-stash-map
   (let ((map (make-sparse-keymap)))
-- 
1.7.8.3



[PATCH v6 4/8] emacs: Add a binding (t) to toggle the truncation of long lines.

2012-02-02 Thread David Edmondson
---
 emacs/notmuch-show.el |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index a07a44a..8d318c9 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1121,6 +1121,7 @@ Refreshes the current view, observing changes in 
cryptographic preferences."
(define-key map "!" 'notmuch-show-toggle-elide-non-matching)
(define-key map "$" 'notmuch-show-toggle-process-crypto)
(define-key map "<" 'notmuch-show-toggle-thread-indentation)
+   (define-key map "t" 'toggle-truncate-lines)
map)
   "Keymap for \"notmuch show\" buffers.")
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)
-- 
1.7.8.3



[PATCH v6 3/8] emacs: Allow the indentation of content to be toggled.

2012-02-02 Thread David Edmondson
Very deeply indented content is sometimes difficult to
read (particular for something like patches). Allow the indentation of
the content to be toggled with '<'.

Indentation of the header lines is not affected, so it remains
possible to see the structure of the thread.
---
 emacs/notmuch-show.el |   26 ++
 1 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index df81cd1..a07a44a 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -145,6 +145,10 @@ indentation."
 (make-variable-buffer-local 'notmuch-show-elide-non-matching-messages)
 (put 'notmuch-show-elide-non-matching-messages 'permanent-local t)

+(defvar notmuch-show-indent-content t)
+(make-variable-buffer-local 'notmuch-show-indent-content)
+(put 'notmuch-show-indent-content 'permanent-local t)
+
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
@@ -255,10 +259,12 @@ operation on the contents of the current buffer."
 (all (buffer-substring (notmuch-show-message-top)
(notmuch-show-message-bottom)))

-(props (notmuch-show-get-message-properties)))
+(props (notmuch-show-get-message-properties))
+(indenting notmuch-show-indent-content))
 (with-temp-buffer
   (insert all)
-  (indent-rigidly (point-min) (point-max) (- depth))
+  (if indenting
+ (indent-rigidly (point-min) (point-max) (- depth)))
   ;; Remove the original header.
   (goto-char (point-min))
   (re-search-forward "^$" (point-max) nil)
@@ -886,7 +892,8 @@ current buffer, if possible."
 (setq notmuch-show-previous-subject bare-subject)

 (setq body-start (point-marker))
-(notmuch-show-insert-body msg (plist-get msg :body) depth)
+(notmuch-show-insert-body msg (plist-get msg :body)
+ (if notmuch-show-indent-content depth 0))
 ;; Ensure that the body ends with a newline.
 (unless (bolp)
   (insert "\n"))
@@ -894,7 +901,8 @@ current buffer, if possible."
 (setq content-end (point-marker))

 ;; Indent according to the depth in the thread.
-(indent-rigidly content-start content-end (* 
notmuch-show-indent-messages-width depth))
+(if notmuch-show-indent-content
+   (indent-rigidly content-start content-end (* 
notmuch-show-indent-messages-width depth)))

 (setq message-end (point-max-marker))

@@ -941,6 +949,15 @@ current buffer, if possible."
 "Showing all messages."))
   (notmuch-show-refresh-view))

+(defun notmuch-show-toggle-thread-indentation ()
+  "Toggle the indentation of threads."
+  (interactive)
+  (setq notmuch-show-indent-content (not notmuch-show-indent-content))
+  (message (if notmuch-show-indent-content
+  "Content is indented."
+"Content is not indented."))
+  (notmuch-show-refresh-view))
+
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
   (let ((msg (car tree))
@@ -1103,6 +1120,7 @@ Refreshes the current view, observing changes in 
cryptographic preferences."
(define-key map "#" 'notmuch-show-print-message)
(define-key map "!" 'notmuch-show-toggle-elide-non-matching)
(define-key map "$" 'notmuch-show-toggle-process-crypto)
+   (define-key map "<" 'notmuch-show-toggle-thread-indentation)
map)
   "Keymap for \"notmuch show\" buffers.")
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)
-- 
1.7.8.3



[PATCH v6 2/8] emacs: Allow `notmuch-show-mode' to display only matching messages.

2012-02-02 Thread David Edmondson
The current behaviour (all messages shown, non-matching collapsed)
is retained as the default. Type '!' to switch to showing only
the matching messages - non-matching messages are not available.
'!' will switch back to showing everything.
---
 emacs/notmuch-show.el |   18 +-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b6329d2..df81cd1 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -141,6 +141,10 @@ indentation."
 (make-variable-buffer-local 'notmuch-show-process-crypto)
 (put 'notmuch-show-process-crypto 'permanent-local t)

+(defvar notmuch-show-elide-non-matching-messages nil)
+(make-variable-buffer-local 'notmuch-show-elide-non-matching-messages)
+(put 'notmuch-show-elide-non-matching-messages 'permanent-local t)
+
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
@@ -928,11 +932,22 @@ current buffer, if possible."
 "Not processing cryptographic MIME parts."))
   (notmuch-show-refresh-view))

+(defun notmuch-show-toggle-elide-non-matching ()
+  "Toggle the display of non-matching messages."
+  (interactive)
+  (setq notmuch-show-elide-non-matching-messages (not 
notmuch-show-elide-non-matching-messages))
+  (message (if notmuch-show-elide-non-matching-messages
+  "Showing matching messages only."
+"Showing all messages."))
+  (notmuch-show-refresh-view))
+
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
   (let ((msg (car tree))
(replies (cadr tree)))
-(notmuch-show-insert-msg msg depth)
+(if (or (not notmuch-show-elide-non-matching-messages)
+   (plist-get msg :match))
+   (notmuch-show-insert-msg msg depth))
 (notmuch-show-insert-thread replies (1+ depth

 (defun notmuch-show-insert-thread (thread depth)
@@ -1086,6 +1101,7 @@ Refreshes the current view, observing changes in 
cryptographic preferences."
(define-key map (kbd "M-RET") 'notmuch-show-open-or-close-all)
(define-key map (kbd "RET") 'notmuch-show-toggle-message)
(define-key map "#" 'notmuch-show-print-message)
+   (define-key map "!" 'notmuch-show-toggle-elide-non-matching)
(define-key map "$" 'notmuch-show-toggle-process-crypto)
map)
   "Keymap for \"notmuch show\" buffers.")
-- 
1.7.8.3



[PATCH v6 1/8] emacs: Rework crypto switch toggle.

2012-02-02 Thread David Edmondson
Re-work the existing crypto switch toggle to be based on a persistant
buffer-local variable.

To allow this, modify `notmuch-show-refresh-view' to erase and re-draw
in the current buffer rather than killing the current buffer and
creating a new one. (This will also allow more per-buffer behaviour in
future patches.)

Add a binding ('$') to toggle crypto processing of the current buffer
and remove the prefix argument approach that achieves a similar
result.
---
 emacs/notmuch-show.el |  126 
 emacs/notmuch.el  |7 +--
 2 files changed, 66 insertions(+), 67 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index de9421e..b6329d2 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -125,6 +125,22 @@ indentation."
 (const :tag "View interactively"
notmuch-show-interactively-view-part)))

+(defvar notmuch-show-thread-id nil)
+(make-variable-buffer-local 'notmuch-show-thread-id)
+(put 'notmuch-show-thread-id 'permanent-local t)
+
+(defvar notmuch-show-parent-buffer nil)
+(make-variable-buffer-local 'notmuch-show-parent-buffer)
+(put 'notmuch-show-parent-buffer 'permanent-local t)
+
+(defvar notmuch-show-query-context nil)
+(make-variable-buffer-local 'notmuch-show-query-context)
+(put 'notmuch-show-query-context 'permanent-local t)
+
+(defvar notmuch-show-process-crypto nil)
+(make-variable-buffer-local 'notmuch-show-process-crypto)
+(put 'notmuch-show-process-crypto 'permanent-local t)
+
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
@@ -411,14 +427,11 @@ message at DEPTH in the current thread."

 (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body)
   (declare (indent 2))
-  (let ((process-crypto (make-symbol "process-crypto")))
-`(let ((,process-crypto notmuch-show-process-crypto))
-   (with-temp-buffer
-(setq notmuch-show-process-crypto ,process-crypto)
-;; Always acquires the part via `notmuch part', even if it is
-;; available in the JSON output.
-(insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
-, at body
+  `(with-temp-buffer
+ ;; Always acquires the part via `notmuch part', even if it is
+ ;; available in the JSON output.
+ (insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
+ , at body))

 (defun notmuch-show-save-part (message-id nth &optional filename content-type)
   (notmuch-with-temp-part-buffer message-id nth
@@ -600,7 +613,7 @@ current buffer, if possible."
   (sigstatus (car (plist-get part :sigstatus
  (notmuch-crypto-insert-sigstatus-button sigstatus from))
   ;; if we're not adding sigstatus, tell the user how they can get it
-  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic mime parts.")))
+  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic MIME parts.")))

   (let ((inner-parts (plist-get part :content))
(start (point)))
@@ -626,7 +639,7 @@ current buffer, if possible."
 (sigstatus (car (plist-get part :sigstatus
(notmuch-crypto-insert-sigstatus-button sigstatus from
   ;; if we're not adding encstatus, tell the user how they can get it
-  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic mime parts.")))
+  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic MIME parts.")))

   (let ((inner-parts (plist-get part :content))
(start (point)))
@@ -753,8 +766,6 @@ current buffer, if possible."

 ;; Helper for parts which are generally not included in the default
 ;; JSON output.
-;; Uses the buffer-local variable notmuch-show-process-crypto to
-;; determine if parts should be decrypted first.
 (defun notmuch-show-get-bodypart-internal (message-id part-number)
   (let ((args '("show" "--format=raw"))
(part-arg (format "--part=%s" part-number)))
@@ -908,6 +919,15 @@ current buffer, if possible."
 ;; criteria.
 (notmuch-show-message-visible msg (plist-get msg :match

+(defun notmuch-show-toggle-process-crypto ()
+  "Toggle the processing of cryptographic MIME parts."
+  (interactive)
+  (setq notmuch-show-process-crypto (not notmuch-show-process-crypto))
+  (message (if notmuch-show-process-crypto
+  "Processing cryptographic MIME parts."
+"Not processing cryptographic MIME parts."))
+  (notmuch-show-refresh-view))
+
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
   (let ((msg (car tree))
@@ -923,15 +943,6 @@ current buffer, if possible."
   "Insert the forest of threads FOREST."
   (mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))

-(defvar notmuch-show-thread-id n

[PATCH v6 0/8] reworked crypto toggle, plus a few other toggles

2012-02-02 Thread David Edmondson
v6:
- add `notmuch-show-only-matching-messages' to allow a user to choose
  that as the default behaviour.
- allow a prefix argument to `notmuch-show' to invert the default
  value of `notmuch-show-only-matching-messages'.

David Edmondson (8):
  emacs: Rework crypto switch toggle.
  emacs: Allow `notmuch-show-mode' to display only matching messages.
  emacs: Allow the indentation of content to be toggled.
  emacs: Add a binding (t) to toggle the truncation of long lines.
  emacs: Optionally retain the state of the buffer during
`notmuch-show-refresh-view'.
  emacs: Check that the parent buffer is alive before using it.
  emacs: Add `notmuch-show-only-matching-messages'.
  emacs: A prefix argument to `notmuch-show' should invert the matching
message behaviour.

 emacs/notmuch-show.el |  224 ++---
 emacs/notmuch.el  |7 +-
 2 files changed, 158 insertions(+), 73 deletions(-)

-- 
1.7.8.3



Re: BiDi

2012-02-02 Thread Clint Adams
On Thu, Feb 02, 2012 at 09:44:07AM -0800, Jameson Graef Rollins wrote:
> More info please.  What is "RTL script"?  Is that "right to left"?  If
> so, yikes.  I can't even imagine what a mess that would have looked
> like.  Another argument against this crazy indenting stuff we do.  I
> hope the thread was also indenting from the right!

Yes, right to left.

Presumably this will be fixed in emacs some year;
http://www.emacswiki.org/emacs/SupportBiDi
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: Possible bug in notmuch python, removing tags not working.

2012-02-02 Thread Justus Winter
Quoting Bryan Hunt (2012-02-01 18:23:11)
>https://bitbucket.org/spaetz/cnotmuch/issue/1/removing-tags-doesnt-seem-to-be-saving

errm... quoting the bug report:
> I've created a trivial python script on Ubuntu, using python-notmuch
> 0.6.1-1 (a bit old, I know).

Please update your notmuch installation and try to reproduce the
bug. If it is still an issue, I'll have a look at it.

Please note that I use the python bindings on a daily basis and have
no trouble adding or removing bugs.

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


Re: [PATCH 1/2] test: add check for filename argument for test_expect_equal_file

2012-02-02 Thread Jameson Graef Rollins
Hey, Dmitry.  I'm so sorry I sent my last email on your original patch
before I saw this new series.  I do now like your original proposal
better, since it shows the diff based the names the caller provides,
which I now agree is probably the clearest and most robust solution.
The second patch in this series could still go through, though, no
matter what version of the change to test_expect_equal_file we go with.

jamie.


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


[PATCH 1/2] test: add check for filename argument for test_expect_equal_file

2012-02-02 Thread Jameson Graef Rollins
Hey, Dmitry.  I'm so sorry I sent my last email on your original patch
before I saw this new series.  I do now like your original proposal
better, since it shows the diff based the names the caller provides,
which I now agree is probably the clearest and most robust solution.
The second patch in this series could still go through, though, no
matter what version of the change to test_expect_equal_file we go with.

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/20120202/347c8b1c/attachment.pgp>


[PATCH v5] add support for user-specified files & directories to ignore

2012-02-02 Thread Tomi Ollila
A new configuration key 'new.ignore' is used to determine which
files and directories user wants not to be scanned as new mails.

Mark the corresponding test as no longer broken
(test from id:"1328105573-4626-1-git-send-email-pie...@praet.org" ).

This work merges my previous attempts and Andreas Amann's work
in id:"ylp7hi23mw8@tyndall.ie"

See notes in id:"20120202-new-ignore-1-git-send-email-...@iki.fi"
---
 notmuch-client.h |9 +
 notmuch-config.c |   30 +-
 notmuch-new.c|   45 +
 test/new |1 -
 4 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index e0eb594..f1762ae 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -250,6 +250,15 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
 const char *new_tags[],
 size_t length);
 
+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config,
+  size_t *length);
+
+void
+notmuch_config_set_new_ignore (notmuch_config_t *config,
+  const char *new_ignore[],
+  size_t length);
+
 notmuch_bool_t
 notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index a124e34..1f01128 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -44,7 +44,10 @@ static const char new_config_comment[] =
 " The following options are supported here:\n"
 "\n"
 "\ttagsA list (separated by ';') of the tags that will be\n"
-"\tadded to all messages incorporated by \"notmuch new\".\n";
+"\tadded to all messages incorporated by \"notmuch new\".\n"
+"\n"
+"\tignore  A list (separated by ';') of file and directory names\n"
+"\tthat will not be searched for messages by \"notmuch new\".\n";
 
 static const char user_config_comment[] =
 " User configuration\n"
@@ -105,6 +108,8 @@ struct _notmuch_config {
 size_t user_other_email_length;
 const char **new_tags;
 size_t new_tags_length;
+const char **new_ignore;
+size_t new_ignore_length;
 notmuch_bool_t maildir_synchronize_flags;
 const char **search_exclude_tags;
 size_t search_exclude_tags_length;
@@ -264,6 +269,8 @@ notmuch_config_open (void *ctx,
 config->user_other_email_length = 0;
 config->new_tags = NULL;
 config->new_tags_length = 0;
+config->new_ignore = NULL;
+config->new_ignore_length = 0;
 config->maildir_synchronize_flags = TRUE;
 config->search_exclude_tags = NULL;
 config->search_exclude_tags_length = 0;
@@ -361,6 +368,10 @@ notmuch_config_open (void *ctx,
notmuch_config_set_new_tags (config, tags, 2);
 }
 
+if (notmuch_config_get_new_ignore (config, &tmp) == NULL) {
+   notmuch_config_set_new_ignore (config, NULL, 0);
+}
+
 if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) {
if (is_new) {
const char *tags[] = { "deleted", "spam" };
@@ -609,6 +620,14 @@ notmuch_config_get_new_tags (notmuch_config_t *config,   
size_t *length)
 &(config->new_tags_length), length);
 }
 
+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config, size_t *length)
+{
+return _config_get_list (config, "new", "ignore",
+&(config->new_ignore),
+&(config->new_ignore_length), length);
+}
+
 void
 notmuch_config_set_user_other_email (notmuch_config_t *config,
 const char *list[],
@@ -627,6 +646,15 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
 &(config->new_tags));
 }
 
+void
+notmuch_config_set_new_ignore (notmuch_config_t *config,
+  const char *list[],
+  size_t length)
+{
+_config_set_list (config, "new", "ignore", list, length,
+&(config->new_ignore));
+}
+
 const char **
 notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t 
*length)
 {
diff --git a/notmuch-new.c b/notmuch-new.c
index a569a54..8a615e6 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -39,6 +39,8 @@ typedef struct {
 int verbose;
 const char **new_tags;
 size_t new_tags_length;
+const char **new_ignore;
+size_t new_ignore_length;
 
 int total_files;
 int processed_files;
@@ -181,6 +183,20 @@ _entries_resemble_maildir (struct dirent **entries, int 
count)
 return 0;
 }
 
+/* Test if the file/directory is to be ignor

Re: Set "From" based on "To" when replying

2012-02-02 Thread Jameson Graef Rollins
On Thu, 02 Feb 2012 19:26:53 +0200, Jani Nikula  wrote:
> Do you have all those email addresses in the user.other_email
> configuration option in your ~/.notmuch-config? It should do the trick,
> though I can see that it might get a bit tedious if you use plenty of
> email addresses like above.

Yeah, I think this is the point: you want "*@mydomain.org" to be one of
the user.other_email.  I don't see why that couldn't be done with a
little work in notmuch-reply.c.  I wouldn't mind seeing this
functionality as well, actually.

jamie.


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


Set "From" based on "To" when replying

2012-02-02 Thread Jameson Graef Rollins
On Thu, 02 Feb 2012 19:26:53 +0200, Jani Nikula  wrote:
> Do you have all those email addresses in the user.other_email
> configuration option in your ~/.notmuch-config? It should do the trick,
> though I can see that it might get a bit tedious if you use plenty of
> email addresses like above.

Yeah, I think this is the point: you want "*@mydomain.org" to be one of
the user.other_email.  I don't see why that couldn't be done with a
little work in notmuch-reply.c.  I wouldn't mind seeing this
functionality as well, actually.

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/20120202/cc8c6038/attachment.pgp>


Re: BiDi

2012-02-02 Thread Jameson Graef Rollins
On Tue, 24 Jan 2012 20:08:14 +, Clint Adams  wrote:
> I just received an email in RTL script and it was rendered incorrectly
> in the emacs interface.  Does anyone know what to do about this?

More info please.  What is "RTL script"?  Is that "right to left"?  If
so, yikes.  I can't even imagine what a mess that would have looked
like.  Another argument against this crazy indenting stuff we do.  I
hope the thread was also indenting from the right!

jamie.


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


[PATCH v4 09/11] test: update tests to reflect the exclude flag

2012-02-02 Thread Mark Walters
notmuch show outputs the exclude flag so many tests using notmuch
show failed. This commit adds "excluded:0" or "excluded: false" to
the expected outputs. After this commit there should be no failing
tests.
---
 test/crypto|9 -
 test/encoding  |2 +-
 test/json  |6 +++---
 test/maildir-sync  |1 +
 test/multipart |4 ++--
 test/thread-naming |   16 
 6 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/test/crypto b/test/crypto
index 446a58b..f29d959 100755
--- a/test/crypto
+++ b/test/crypto
@@ -43,6 +43,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -77,6 +78,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -113,6 +115,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -153,7 +156,7 @@ test_begin_subtest "decryption, --format=text"
 output=$(notmuch show --format=text --decrypt subject:"test encrypted message 
001" \
 | notmuch_show_sanitize_all \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
-expected='message{ id:X depth:0 match:1 filename:X
+expected='message{ id:X depth:0 match:1 excluded:0 filename:X
 header{
 Notmuch Test Suite  (2000-01-01) (encrypted inbox)
 Subject: test encrypted message 001
@@ -187,6 +190,7 @@ output=$(notmuch show --format=json --decrypt subject:"test 
encrypted message 00
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -242,6 +246,7 @@ output=$(notmuch show --format=json --decrypt subject:"test 
encrypted message 00
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -277,6 +282,7 @@ output=$(notmuch show --format=json --decrypt subject:"test 
encrypted message 00
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
@@ -332,6 +338,7 @@ output=$(notmuch show --format=json --verify subject:"test 
signed message 001" \
 | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "X",
  "match": true,
+ "excluded": false,
  "filename": "Y",
  "timestamp": 946728000,
  "date_relative": "2000-01-01",
diff --git a/test/encoding b/test/encoding
index 33259c1..a872345 100755
--- a/test/encoding
+++ b/test/encoding
@@ -6,7 +6,7 @@ test_begin_subtest "Message with text of unknown charset"
 add_message '[content-type]="text/plain; charset=unknown-8bit"' \
"[body]=irrelevant"
 output=$(notmuch show id:${gen_msg_id} 2>&1 | notmuch_show_sanitize)
-test_expect_equal "$output" "message{ id:msg-001@notmuch-test-suite depth:0 
match:1 filename:/XXX/mail/msg-001
+test_expect_equal "$output" "message{ id:msg-001@notmuch-test-suite depth:0 
match:1 excluded:0 filename:/XXX/mail/msg-001
 header{
 Notmuch Test Suite  (2001-01-05) (inbox unread)
 Subject: Test message #1
diff --git a/test/json b/test/json
index 7df4380..f95fcf8 100755
--- a/test/json
+++ b/test/json
@@ -5,7 +5,7 @@ test_description="--format=json output"
 test_begin_subtest "Show message: json"
 add_message "[subject]=\"json-show-subject\"" "[date]=\"Sat, 01 Jan 2000 
12:00:00 -\"" "[body]=\"json-show-message\""
 output=$(notmuch show --format=json "json-show-message")
-test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, 
\"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, 
\"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], 
\"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test 
Suite \", \"To\": \"Notmuch Test Suite 
\", \"Cc\": \"\", \"Bcc\": \"\", \"Date\": \"Sat, 
01 Jan 2000 12:00:00 -\"}, \"body\": [{\"id\": 1, \"content-type\": 
\"text/plain\", \"content\": \"json-show-message\n\"}]}, ["
+test_expect_equal "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, 
\"excluded\": false, \"filename\": \"${gen_msg_filename}\", \

[PATCH v4 11/11] emacs: show: recognize the exclude flag.

2012-02-02 Thread Mark Walters
Show mode will recognize the exclude flag by not opening excluding
messages by default, and will start at the first matching non-excluded
message. If there are no matching non-excluded messages it will go to
the first matching (necessarily excluded) message.
---
 emacs/notmuch-show.el |   18 +-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 84ac624..8efadf6 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -905,7 +905,8 @@ current buffer, if possible."
 
 ;; Message visibility depends on whether it matched the search
 ;; criteria.
-(notmuch-show-message-visible msg (plist-get msg :match
+(notmuch-show-message-visible msg (and (plist-get msg :match)
+  (not (plist-get msg :excluded))
 
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
@@ -1015,6 +1016,9 @@ buffer."
 ;; Move straight to the first open message
 (unless (notmuch-show-message-visible-p)
   (notmuch-show-next-open-message))
+(when (eq (point) (point-max))
+  (goto-char (point-min))
+  (notmuch-show-next-matching-message))
 
 ;; Set the header line to the subject of the first open message.
 (setq header-line-format (notmuch-show-strip-re 
(notmuch-show-get-subject)))
@@ -1417,6 +1421,18 @@ any effects from previous calls to
  (notmuch-show-message-adjust))
   (goto-char (point-max)
 
+(defun notmuch-show-next-matching-message ()
+  "Show the next matching message."
+  (interactive)
+  (let (r)
+(while (and (setq r (notmuch-show-goto-message-next))
+   (not (notmuch-show-get-prop :match
+(if r
+   (progn
+ (notmuch-show-mark-read)
+ (notmuch-show-message-adjust))
+  (goto-char (point-max)
+
 (defun notmuch-show-previous-open-message ()
   "Show the previous message."
   (interactive)
-- 
1.7.2.3

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


[PATCH v4 10/11] cli: omit excluded messages in results where appropriate.

2012-02-02 Thread Mark Walters
In all cases of notmuch count/search/show where the results returned
cannot reflect the exclude flag return just the matched not-excluded
results. If the caller wishes to have all the matched results (i.e.,
including the excluded ones) they should call with the
--no-exclude option.

The relevant cases are
count: both threads and messages
search: all cases except the summary view
show: mbox format
---
 notmuch-count.c  |2 ++
 notmuch-search.c |9 +
 notmuch-show.c   |5 +
 3 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 5364507..46b76ae 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -88,6 +88,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
 }
 
+notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 switch (output) {
 case OUTPUT_MESSAGES:
printf ("%u\n", notmuch_query_count_messages (query));
diff --git a/notmuch-search.c b/notmuch-search.c
index 43ec90b..d2b2488 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -207,6 +207,9 @@ do_search_threads (const search_format_t *format,
 int first_thread = 1;
 int i;
 
+if (output == OUTPUT_THREADS)
+   notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 if (offset < 0) {
offset += notmuch_query_count_threads (query);
if (offset < 0)
@@ -297,6 +300,8 @@ do_search_messages (const search_format_t *format,
 int first_message = 1;
 int i;
 
+notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 if (offset < 0) {
offset += notmuch_query_count_messages (query);
if (offset < 0)
@@ -368,6 +373,10 @@ do_search_tags (notmuch_database_t *notmuch,
 const char *tag;
 int first_tag = 1;
 
+notmuch_query_set_omit_excluded_messages (query, TRUE);
+/* should the following only special case if no excluded terms
+ * specified? */
+
 /* Special-case query of "*" for better performance. */
 if (strcmp (notmuch_query_get_query_string (query), "*") == 0) {
tags = notmuch_database_get_all_tags (notmuch);
diff --git a/notmuch-show.c b/notmuch-show.c
index 108f13b..924e7ea 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1166,6 +1166,11 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
return 1;
 }
 
+/* if format=mbox then we can not output excluded messages as
+ * there is no way to make the exclude flag available */
+if (mbox)
+   notmuch_query_set_omit_excluded_messages (query, TRUE);
+
 /* if part was requested and format was not specified, use format=raw */
 if (params.part >= 0 && !format_specified)
format = &format_raw;
-- 
1.7.2.3

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


BiDi

2012-02-02 Thread Jameson Graef Rollins
On Tue, 24 Jan 2012 20:08:14 +, Clint Adams  wrote:
> I just received an email in RTL script and it was rendered incorrectly
> in the emacs interface.  Does anyone know what to do about this?

More info please.  What is "RTL script"?  Is that "right to left"?  If
so, yikes.  I can't even imagine what a mess that would have looked
like.  Another argument against this crazy indenting stuff we do.  I
hope the thread was also indenting from the right!

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/20120202/d9ce0965/attachment-0001.pgp>


[PATCH v4 08/11] cli: Make notmuch-show respect excludes.

2012-02-02 Thread Mark Walters
This adds the excludes to notmuch-show.c. We do not exclude when only
a single message (or part) is requested. notmuch-show will output the
exclude information when either text or json format is requested. As
this changes the output from notmuch-show it breaks many tests (in a
trivial and expected fashion).
---
 notmuch-show.c |   24 
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index dec799c..108f13b 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -193,10 +193,11 @@ _get_one_line_summary (const void *ctx, notmuch_message_t 
*message)
 static void
 format_message_text (unused (const void *ctx), notmuch_message_t *message, int 
indent)
 {
-printf ("id:%s depth:%d match:%d filename:%s\n",
+printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n",
notmuch_message_get_message_id (message),
indent,
-   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
+   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 
: 0,
+   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
1 : 0,
notmuch_message_get_filename (message));
 }
 
@@ -212,9 +213,10 @@ format_message_json (const void *ctx, notmuch_message_t 
*message, unused (int in
 date = notmuch_message_get_date (message);
 relative_date = notmuch_time_relative_date (ctx, date);
 
-printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, 
\"date_relative\": \"%s\", \"tags\": [",
+printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, 
\"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
json_quote_str (ctx_quote, notmuch_message_get_message_id 
(message)),
notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 
"true" : "false",
+   notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 
"true" : "false",
json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
date, relative_date);
 
@@ -1059,9 +1061,13 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
 char *opt;
 const notmuch_show_format_t *format = &format_text;
 notmuch_show_params_t params;
+const char **search_exclude_tags;
+size_t search_exclude_tags_length;
 int mbox = 0;
 int format_specified = 0;
 int i;
+notmuch_bool_t no_exclude = FALSE;
+unsigned int j;
 
 params.entire_thread = 0;
 params.raw = 0;
@@ -1098,6 +1104,8 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
params.part = atoi(argv[i] + sizeof ("--part=") - 1);
} else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {
params.entire_thread = 1;
+   } else if (STRNCMP_LITERAL (argv[i], "--no-exclude") == 0) {
+   no_exclude = TRUE;
} else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
   (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
if (params.cryptoctx == NULL) {
@@ -1167,10 +1175,18 @@ notmuch_show_command (void *ctx, unused (int argc), 
unused (char *argv[]))
 if (params.raw && params.part < 0)
params.part = 0;
 
+/* If a single message is requested we do not use search_excludes. */
 if (params.part >= 0)
return do_show_single (ctx, query, format, ¶ms);
-else
+else {
+   if (!no_exclude) {
+   search_exclude_tags = notmuch_config_get_search_exclude_tags
+   (config, &search_exclude_tags_length);
+   for (j = 0; j < search_exclude_tags_length; j++)
+   notmuch_query_add_tag_exclude (query, search_exclude_tags[j]);
+   }
return do_show (ctx, query, format, ¶ms);
+}
 
 notmuch_query_destroy (query);
 notmuch_database_close (notmuch);
-- 
1.7.2.3

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


[PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages

2012-02-02 Thread Mark Walters
The function is
notmuch_thread_get_flag_messages
(notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)

and returns the number of messages with the specified flags on flag_mask.

This generalises the existing function
notmuch_thread_get_total_messages and
notmuch_thread_get_matched_messages which are retained to maintain
compatibility.
---
 lib/message.cc |6 +++---
 lib/notmuch.h  |   15 +--
 lib/thread.cc  |   39 ++-
 3 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 0075425..d60da83 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -746,7 +746,7 @@ notmuch_bool_t
 notmuch_message_get_flag (notmuch_message_t *message,
  notmuch_message_flag_t flag)
 {
-return message->flags & (1 << flag);
+return message->flags & flag;
 }
 
 void
@@ -754,9 +754,9 @@ notmuch_message_set_flag (notmuch_message_t *message,
  notmuch_message_flag_t flag, notmuch_bool_t enable)
 {
 if (enable)
-   message->flags |= (1 << flag);
+   message->flags |= flag;
 else
-   message->flags &= ~(1 << flag);
+   message->flags &= ~flag;
 }
 
 time_t
diff --git a/lib/notmuch.h b/lib/notmuch.h
index f75afae..c02e7f4 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -654,6 +654,16 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread);
 int
 notmuch_thread_get_total_messages (notmuch_thread_t *thread);
 
+/* Get the number of messages in 'thread' which have the specified
+ * flags on flag_mask.
+ *
+ * This is a more general interface than
+ * notmuch_thread_get_total_messages or
+ * notmuch_thread_get_matched_messages
+ */
+int
+notmuch_thread_get_flag_messages (notmuch_thread_t *thread, unsigned int 
flag_mask, unsigned int flags);
+
 /* Get a notmuch_messages_t iterator for the top-level messages in
  * 'thread'.
  *
@@ -902,8 +912,9 @@ notmuch_message_get_filenames (notmuch_message_t *message);
 
 /* Message flags */
 typedef enum _notmuch_message_flag {
-NOTMUCH_MESSAGE_FLAG_MATCH,
-NOTMUCH_MESSAGE_FLAG_EXCLUDED
+NOTMUCH_MESSAGE_FLAG_MATCH = (1<<0),
+NOTMUCH_MESSAGE_FLAG_EXCLUDED = (1<<1),
+NOTMUCH_MESSAGE_FLAG_MAX  = (1<<2)
 } notmuch_message_flag_t;
 
 /* Get a value of a flag for the email corresponding to 'message'. */
diff --git a/lib/thread.cc b/lib/thread.cc
index e976d64..542f7f4 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -37,8 +37,7 @@ struct visible _notmuch_thread {
 
 notmuch_message_list_t *message_list;
 GHashTable *message_hash;
-int total_messages;
-int matched_messages;
+int flag_count_messages[NOTMUCH_MESSAGE_FLAG_MAX];
 time_t oldest;
 time_t newest;
 };
@@ -226,7 +225,6 @@ _thread_add_message (notmuch_thread_t *thread,
 
 _notmuch_message_list_add_message (thread->message_list,
   talloc_steal (thread, message));
-thread->total_messages++;
 
 g_hash_table_insert (thread->message_hash,
 xstrdup (notmuch_message_get_message_id (message)),
@@ -319,21 +317,18 @@ _thread_add_matched_message (notmuch_thread_t *thread,
 
 date = notmuch_message_get_date (message);
 
-if (date < thread->oldest || ! thread->matched_messages) {
+if (date < thread->oldest || ! notmuch_thread_get_matched_messages 
(thread)) {
thread->oldest = date;
if (sort == NOTMUCH_SORT_OLDEST_FIRST)
_thread_set_subject_from_message (thread, message);
 }
 
-if (date > thread->newest || ! thread->matched_messages) {
+if (date > thread->newest || ! notmuch_thread_get_matched_messages 
(thread)) {
thread->newest = date;
if (sort != NOTMUCH_SORT_OLDEST_FIRST)
_thread_set_subject_from_message (thread, message);
 }
 
-if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
-   thread->matched_messages++;
-
 if (g_hash_table_lookup_extended (thread->message_hash,
notmuch_message_get_message_id (message), NULL,
(void **) &hashed_message)) {
@@ -411,7 +406,7 @@ _notmuch_thread_create (void *ctx,
 const char *thread_id;
 char *thread_id_query_string;
 notmuch_query_t *thread_id_query;
-
+int i;
 notmuch_messages_t *messages;
 notmuch_message_t *message;
 
@@ -457,8 +452,8 @@ _notmuch_thread_create (void *ctx,
 thread->message_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
  free, NULL);
 
-thread->total_messages = 0;
-thread->matched_messages = 0;
+for (i = 0; i < NOTMUCH_MESSAGE_FLAG_MAX; i++)
+   thread->flag_count_messages[i] = 0;
 thread->oldest = 0;
 thread->newest = 0;
 
@@ -473,6 +468,7 @@ _notmuch_thread_create (void *ctx,
 notmuch_messages_move_to_next (messages))
 {
unsigned int doc_id;
+   unsigned int message_flags;
 
message =

[PATCH v4 06/11] lib: Add the exclude flag to notmuch_query_search_threads

2012-02-02 Thread Mark Walters
Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to
notmuch_query_search_threads. Implemented by inspecting the tags
directly in _notmuch_thread_create/_thread_add_message rather than as
a Xapian query for speed reasons.
---
 lib/notmuch-private.h |7 +--
 lib/query.cc  |1 +
 lib/thread.cc |   18 +++---
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index e791bb0..ea836f7 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -148,6 +148,8 @@ typedef enum _notmuch_private_status {
 
 typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
 
+typedef struct _notmuch_string_list notmuch_string_list_t;
+
 /* database.cc */
 
 /* Lookup a prefix value by name.
@@ -216,6 +218,7 @@ _notmuch_thread_create (void *ctx,
notmuch_database_t *notmuch,
unsigned int seed_doc_id,
notmuch_doc_id_set_t *match_set,
+   notmuch_string_list_t *excluded_terms,
notmuch_sort_t sort);
 
 /* message.cc */
@@ -459,11 +462,11 @@ typedef struct _notmuch_string_node {
 struct _notmuch_string_node *next;
 } notmuch_string_node_t;
 
-typedef struct visible _notmuch_string_list {
+struct visible _notmuch_string_list {
 int length;
 notmuch_string_node_t *head;
 notmuch_string_node_t **tail;
-} notmuch_string_list_t;
+};
 
 notmuch_string_list_t *
 _notmuch_string_list_create (const void *ctx);
diff --git a/lib/query.cc b/lib/query.cc
index 90a71a1..e1c3977 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -472,6 +472,7 @@ notmuch_threads_get (notmuch_threads_t *threads)
   threads->query->notmuch,
   doc_id,
   &threads->match_set,
+  threads->query->exclude_terms,
   threads->query->sort);
 }
 
diff --git a/lib/thread.cc b/lib/thread.cc
index 0435ee6..e976d64 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread,
  */
 static void
 _thread_add_message (notmuch_thread_t *thread,
-notmuch_message_t *message)
+notmuch_message_t *message,
+notmuch_string_list_t *exclude_terms)
 {
 notmuch_tags_t *tags;
 const char *tag;
@@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread,
 notmuch_tags_move_to_next (tags))
 {
tag = notmuch_tags_get (tags);
+   /* Mark excluded messages. */
+   for (notmuch_string_node_t *term = exclude_terms->head; term;
+term = term->next) {
+   /* We ignore initial 'K'. */
+   if (strcmp(tag, (term->string + 1)) == 0) {
+   notmuch_message_set_flag (message, 
NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
+   break;
+   }
+   }
g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
 }
 }
@@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread,
_thread_set_subject_from_message (thread, message);
 }
 
-thread->matched_messages++;
+if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
+   thread->matched_messages++;
 
 if (g_hash_table_lookup_extended (thread->message_hash,
notmuch_message_get_message_id (message), NULL,
@@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx,
notmuch_database_t *notmuch,
unsigned int seed_doc_id,
notmuch_doc_id_set_t *match_set,
+   notmuch_string_list_t *exclude_terms,
notmuch_sort_t sort)
 {
 notmuch_thread_t *thread;
@@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx,
if (doc_id == seed_doc_id)
message = seed_message;
 
-   _thread_add_message (thread, message);
+   _thread_add_message (thread, message, exclude_terms);
 
if ( _notmuch_doc_id_set_contains (match_set, doc_id)) {
_notmuch_doc_id_set_remove (match_set, doc_id);
-- 
1.7.2.3

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


[PATCH v4 05/11] lib: Make notmuch_query_search_messages set the exclude flag

2012-02-02 Thread Mark Walters
Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by
notmuch_query_search_messages for excluded messages. Also add an
option omit_excluded_messages to the search that we do not want the
excludes at all.

This exclude flag will be added to notmuch_query_search threads in the
next patch.
---
 lib/notmuch-private.h |1 +
 lib/notmuch.h |   10 -
 lib/query.cc  |   52 +---
 3 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 7bf153e..e791bb0 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -401,6 +401,7 @@ typedef struct _notmuch_message_list {
  */
 struct visible _notmuch_messages {
 notmuch_bool_t is_of_list_type;
+notmuch_doc_id_set_t *excluded_doc_ids;
 notmuch_message_node_t *iterator;
 };
 
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 7929fe7..f75afae 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -449,6 +449,13 @@ typedef enum {
 const char *
 notmuch_query_get_query_string (notmuch_query_t *query);
 
+/* Specify whether to results should omit the excluded results rather
+ * than just marking them excluded. This is useful for passing a
+ * notmuch_messages_t not containing the excluded messages to other
+ * functions. */
+void
+notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, 
notmuch_bool_t omit);
+
 /* Specify the sorting desired for this query. */
 void
 notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
@@ -895,7 +902,8 @@ notmuch_message_get_filenames (notmuch_message_t *message);
 
 /* Message flags */
 typedef enum _notmuch_message_flag {
-NOTMUCH_MESSAGE_FLAG_MATCH
+NOTMUCH_MESSAGE_FLAG_MATCH,
+NOTMUCH_MESSAGE_FLAG_EXCLUDED
 } notmuch_message_flag_t;
 
 /* Get a value of a flag for the email corresponding to 'message'. */
diff --git a/lib/query.cc b/lib/query.cc
index c25b301..90a71a1 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -28,6 +28,7 @@ struct _notmuch_query {
 const char *query_string;
 notmuch_sort_t sort;
 notmuch_string_list_t *exclude_terms;
+notmuch_bool_t omit_excluded_messages;
 };
 
 typedef struct _notmuch_mset_messages {
@@ -57,6 +58,12 @@ struct visible _notmuch_threads {
 notmuch_doc_id_set_t match_set;
 };
 
+/* We need this in the message functions so forward declare. */
+static notmuch_bool_t
+_notmuch_doc_id_set_init (void *ctx,
+ notmuch_doc_id_set_t *doc_ids,
+ GArray *arr);
+
 notmuch_query_t *
 notmuch_query_create (notmuch_database_t *notmuch,
  const char *query_string)
@@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
 
 query->exclude_terms = _notmuch_string_list_create (query);
 
+query->omit_excluded_messages = FALSE;
+
 return query;
 }
 
@@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query)
 }
 
 void
+notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, 
notmuch_bool_t omit)
+{
+query->omit_excluded_messages = omit;
+}
+
+void
 notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort)
 {
 query->sort = sort;
@@ -173,6 +188,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
   "mail"));
Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
+   Xapian::MSetIterator iterator;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
  Xapian::QueryParser::FLAG_PHRASE |
  Xapian::QueryParser::FLAG_LOVEHATE |
@@ -190,11 +206,35 @@ notmuch_query_search_messages (notmuch_query_t *query)
final_query = Xapian::Query (Xapian::Query::OP_AND,
 mail_query, string_query);
}
+   messages->base.excluded_doc_ids = NULL;
+
+   if (query->exclude_terms) {
+   exclude_query = _notmuch_exclude_tags (query, final_query);
+   exclude_query = Xapian::Query (Xapian::Query::OP_AND,
+  exclude_query, final_query);
+
+   if (query->omit_excluded_messages)
+   final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+final_query, exclude_query);
+   else {
+   enquire.set_weighting_scheme (Xapian::BoolWeight());
+   enquire.set_query (exclude_query);
+
+   mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount 
());
+
+   GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof 
(unsigned int));
+
+   for (iterator = mset.begin (); iterator != mset.end (); 
iterator++) {
+   unsigned int doc_id = *iterator;
+   g_array_append_val (excluded_doc_ids, doc_id);
+   }
+   messages->base.excluded_doc_ids = talloc (query, 
_notmuc

[PATCH v4 04/11] lib: Rearrange the exclude code in query.cc

2012-02-02 Thread Mark Walters
Slightly refactor the exclude code to give the callers access to the
exclude query itself. There should be no functional change.
---
 lib/query.cc |   29 +++--
 1 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index 0b36602..c25b301 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -122,12 +122,15 @@ _notmuch_messages_destructor (notmuch_mset_messages_t 
*messages)
 return 0;
 }
 
-/* Return a query that does not match messages with the excluded tags
- * registered with the query.  Any tags that explicitly appear in
- * xquery will not be excluded. */
+/* Return a query that matches messages with the excluded tags
+ * registered with query.  Any tags that explicitly appear in xquery
+ * will not be excluded. The caller of this function has to combine
+ * the returned query appropriately.*/
 static Xapian::Query
 _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
 {
+Xapian::Query exclude_query = Xapian::Query::MatchNothing;
+
 for (notmuch_string_node_t *term = query->exclude_terms->head; term;
 term = term->next) {
Xapian::TermIterator it = xquery.get_terms_begin ();
@@ -137,10 +140,10 @@ _notmuch_exclude_tags (notmuch_query_t *query, 
Xapian::Query xquery)
break;
}
if (it == end)
-   xquery = Xapian::Query (Xapian::Query::OP_AND_NOT,
-   xquery, Xapian::Query (term->string));
+   exclude_query = Xapian::Query (Xapian::Query::OP_OR,
+   exclude_query, Xapian::Query 
(term->string));
 }
-return xquery;
+return exclude_query;
 }
 
 notmuch_messages_t *
@@ -168,7 +171,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
   _find_prefix ("type"),
   "mail"));
-   Xapian::Query string_query, final_query;
+   Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
  Xapian::QueryParser::FLAG_PHRASE |
@@ -188,7 +191,10 @@ notmuch_query_search_messages (notmuch_query_t *query)
 mail_query, string_query);
}
 
-   final_query = _notmuch_exclude_tags (query, final_query);
+   exclude_query = _notmuch_exclude_tags (query, final_query);
+
+   final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+final_query, exclude_query);
 
enquire.set_weighting_scheme (Xapian::BoolWeight());
 
@@ -449,7 +455,7 @@ notmuch_query_count_messages (notmuch_query_t *query)
Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
   _find_prefix ("type"),
   "mail"));
-   Xapian::Query string_query, final_query;
+   Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
  Xapian::QueryParser::FLAG_PHRASE |
@@ -469,7 +475,10 @@ notmuch_query_count_messages (notmuch_query_t *query)
 mail_query, string_query);
}
 
-   final_query = _notmuch_exclude_tags (query, final_query);
+   exclude_query = _notmuch_exclude_tags (query, final_query);
+
+   final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
+final_query, exclude_query);
 
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);
-- 
1.7.2.3

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


[PATCH v4 03/11] test: add tests for new cli --no-exclude option

2012-02-02 Thread Mark Walters
The tests test the new --no-exclude option to search and count.
There were no existing tests for the exclude behaviour for count so
added these too.
---
 test/count  |   21 +
 test/search |5 +
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/test/count b/test/count
index 300b171..976fff1 100755
--- a/test/count
+++ b/test/count
@@ -37,4 +37,25 @@ test_expect_equal \
 "0" \
 "`notmuch count --output=threads ${SEARCH}`"
 
+test_begin_subtest "count excluding \"deleted\" messages"
+notmuch config set search.exclude_tags = deleted
+generate_message '[subject]="Not deleted"'
+generate_message '[subject]="Another not deleted"'
+generate_message '[subject]="Deleted"'
+notmuch new > /dev/null
+notmuch tag +deleted id:$gen_msg_id
+test_expect_equal \
+"2" \
+"`notmuch count subject:deleted`"
+
+test_begin_subtest "count \"deleted\" messages, exclude overridden"
+test_expect_equal \
+"1" \
+"`notmuch count subject:deleted and tag:deleted`"
+
+test_begin_subtest "count \"deleted\" messages, with --no-exclude"
+test_expect_equal \
+"3" \
+"`notmuch count --no-exclude subject:deleted`"
+
 test_done
diff --git a/test/search b/test/search
index 414be35..3da5d17 100755
--- a/test/search
+++ b/test/search
@@ -148,6 +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 when --no-exclude 
specified"
+output=$(notmuch search --no-exclude 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_begin_subtest "Don't exclude \"deleted\" messages from search if not 
configured"
 notmuch config set search.exclude_tags
 output=$(notmuch search subject:deleted | notmuch_search_sanitize)
-- 
1.7.2.3

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


[PATCH v4 02/11] cli: Add --no-exclude to the man pages for search and count

2012-02-02 Thread Mark Walters
---
 man/man1/notmuch-count.1  |7 +++
 man/man1/notmuch-search.1 |7 +++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/man/man1/notmuch-count.1 b/man/man1/notmuch-count.1
index 25fe329..413b405 100644
--- a/man/man1/notmuch-count.1
+++ b/man/man1/notmuch-count.1
@@ -38,6 +38,13 @@ Output the number of matching messages. This is the default.
 Output the number of matching threads.
 .RE
 .RE
+
+.RS 4
+.TP 4
+.BR \-\-no\-exclude
+
+Do not exclude the messages matching search_exclude_tags in the config file.
+.RE
 .RE
 .RE
 
diff --git a/man/man1/notmuch-search.1 b/man/man1/notmuch-search.1
index 0bc3f40..bc54b4d 100644
--- a/man/man1/notmuch-search.1
+++ b/man/man1/notmuch-search.1
@@ -112,6 +112,13 @@ result from the end.
 Limit the number of displayed results to N.
 .RE
 
+.RS 4
+.TP 4
+.BR \-\-no\-exclude
+
+Do not exclude the messages matching search_exclude_tags in the config file.
+.RE
+
 .SH SEE ALSO
 
 \fBnotmuch\fR(1), \fBnotmuch-config\fR(1), \fBnotmuch-count\fR(1),
-- 
1.7.2.3

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


[PATCH v4 01/11] cli: add --no-exclude option to count and search.

2012-02-02 Thread Mark Walters
This option turns off the exclusion so all matching messages are
returned. We do not need to add this to notmuch-show as that does not
(yet) exclude.
---
 notmuch-count.c  |   17 +++--
 notmuch-search.c |   17 +++--
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 63459fb..5364507 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -35,8 +35,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 char *query_str;
 int opt_index;
 int output = OUTPUT_MESSAGES;
-const char **search_exclude_tags;
-size_t search_exclude_tags_length;
+notmuch_bool_t no_exclude = FALSE;
 unsigned int i;
 
 notmuch_opt_desc_t options[] = {
@@ -44,6 +43,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
  (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS },
  { "messages", OUTPUT_MESSAGES },
  { 0, 0 } } },
+   { NOTMUCH_OPT_BOOLEAN, &no_exclude, "no-exclude", 'd', 0 },
{ 0, 0, 0, 0, 0 }
 };
 
@@ -78,10 +78,15 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
return 1;
 }
 
-search_exclude_tags = notmuch_config_get_search_exclude_tags
-   (config, &search_exclude_tags_length);
-for (i = 0; i < search_exclude_tags_length; i++)
-   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+if (!no_exclude) {
+   const char **search_exclude_tags;
+   size_t search_exclude_tags_length;
+
+   search_exclude_tags = notmuch_config_get_search_exclude_tags
+   (config, &search_exclude_tags_length);
+   for (i = 0; i < search_exclude_tags_length; i++)
+   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+}
 
 switch (output) {
 case OUTPUT_MESSAGES:
diff --git a/notmuch-search.c b/notmuch-search.c
index d504051..43ec90b 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -423,8 +423,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 output_t output = OUTPUT_SUMMARY;
 int offset = 0;
 int limit = -1; /* unlimited */
-const char **search_exclude_tags;
-size_t search_exclude_tags_length;
+notmuch_bool_t no_exclude = FALSE;
 unsigned int i;
 
 enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT }
@@ -446,6 +445,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
  { "files", OUTPUT_FILES },
  { "tags", OUTPUT_TAGS },
  { 0, 0 } } },
+{ NOTMUCH_OPT_BOOLEAN, &no_exclude, "no-exclude", 'd', 0 },
{ NOTMUCH_OPT_INT, &offset, "offset", 'O', 0 },
{ NOTMUCH_OPT_INT, &limit, "limit", 'L', 0  },
{ 0, 0, 0, 0, 0 }
@@ -493,10 +493,15 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 
 notmuch_query_set_sort (query, sort);
 
-search_exclude_tags = notmuch_config_get_search_exclude_tags
-   (config, &search_exclude_tags_length);
-for (i = 0; i < search_exclude_tags_length; i++)
-   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+if (!no_exclude) {
+   const char **search_exclude_tags;
+   size_t search_exclude_tags_length;
+
+   search_exclude_tags = notmuch_config_get_search_exclude_tags
+   (config, &search_exclude_tags_length);
+   for (i = 0; i < search_exclude_tags_length; i++)
+   notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+}
 
 switch (output) {
 default:
-- 
1.7.2.3

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


Re: [PATCH] test: make test_expect_equal_file() arguments flexible

2012-02-02 Thread Jameson Graef Rollins
On Wed,  1 Feb 2012 11:19:54 +0400, Dmitry Kurochkin 
 wrote:
> Before the change, test_expect_equal_file() function treated the first
> argument as "actual output file" and the second argument as "expected
> output file".  When the test fails, the files are copied for later
> inspection.  The first files was copied to "$testname.output" and the
> second file to "$testname.expected".  The argument order for
> test_expect_equal_file() is often wrong which results in confusing
> diff output and incorrectly named files.

After thinking about this some more, I'm taking it all back.  I think
this is a fine solution, since it just goes with whatever name the test
is invoked with.  Since this is usually just OUTPUT and EXPECTED, it
should all be clear, and the diffs should be fine, even if the ordering
is permuted some places.  Sorry about all the chatter.

+1

jamie.


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


[PATCH] test: make test_expect_equal_file() arguments flexible

2012-02-02 Thread Jameson Graef Rollins
On Wed,  1 Feb 2012 11:19:54 +0400, Dmitry Kurochkin  wrote:
> Before the change, test_expect_equal_file() function treated the first
> argument as "actual output file" and the second argument as "expected
> output file".  When the test fails, the files are copied for later
> inspection.  The first files was copied to "$testname.output" and the
> second file to "$testname.expected".  The argument order for
> test_expect_equal_file() is often wrong which results in confusing
> diff output and incorrectly named files.

After thinking about this some more, I'm taking it all back.  I think
this is a fine solution, since it just goes with whatever name the test
is invoked with.  Since this is usually just OUTPUT and EXPECTED, it
should all be clear, and the diffs should be fine, even if the ordering
is permuted some places.  Sorry about all the chatter.

+1

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/20120202/99189dc3/attachment.pgp>


[Patch V4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag

2012-02-02 Thread Mark Walters

Here is the latest version of this patch set. I think I have fixed most
of the problems raised in review but there are some remaining issues
detailed below.

Changes and queries:

1) Changed --do-not-exclude option to --no-exclude

2) The api notmuch_query_set_omit_excluded_messages remains: without it I
can't see how a user can pass the notmuch_messages_t object around which
does not contain the excluded messages. See
id:"87fweusabh@qmul.ac.uk"

3) I have introduced a new function notmuch_thread_get_flag_messages
(notmuch_thread_t *thread, unsigned int flag_mask, unsigned int flags)

which returns the number of messages with the specified flags on
flag_mask. (Note the current NOTMUCH_MESSAGE_FLAGs were nominally the
bit position of the flag rather than the actual bit of the flag. I
changed that. I am not completely happy with the style for this commit
(patch 7/11): any comments gratefully received!

4) In id:"20120131044352.gz17...@mit.edu" Austin suggested that I use a
notmuch_mset_messages_t object rather than an notmuch_doc_id_set_t. I
couldn't see how that would work unless the iterator would generate the
excludes in step with the main query. At the moment the doc_id object
just stores a bitmap listing all relevant excluded messages.

5) If we have a query which overrides the excludes such as "blah and
tag:deleted" should the tag:deleted messages still be marked excluded?
The current implementation does mark them excluded but my preference would
be not to. What do people think?

6) In id:"20120131050748.ga10...@mit.edu" Austin pointed out that the
sort will be influenced by the excluded messages. I do not think either
of us are sure whether it should be or not so I have left it as is for
the moment.

Best wishes

Mark






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


Re: Set "From" based on "To" when replying

2012-02-02 Thread Jani Nikula
On Sat, 21 Jan 2012 16:35:10 +0100, Simon Campese  
wrote:
> Dear Community,
> 
> I've got my own domain and when registering or shopping at some website,
> I always use email addresses of the form "websiten...@mydomain.org", so
> for example I use "ama...@mydomain.org" when shopping at amazon. The
> reason for this is categorizing incoming mail on the one hand, and
> immediately being able to spot the source of spam on the other hand. 
> 
> I would like to implement the following behaviour: When replying to a
> mail that has "someth...@mydomain.org" in the "To"-header, I would like
> to have the "From"-header of the reply to be automatically set to this
> address. 
> 
> Is there some kind of reply-hook in notmuch where one could put an
> appropriate function? 

Do you have all those email addresses in the user.other_email
configuration option in your ~/.notmuch-config? It should do the trick,
though I can see that it might get a bit tedious if you use plenty of
email addresses like above.

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


Re: [PATCH] add support for user-specified files & directories to ignore

2012-02-02 Thread Jani Nikula

Hi Tomi, please find a few more comments and nitpicks inline. No need to
roll another version for them, though.

BR,
Jani.

On Thu,  2 Feb 2012 17:17:33 +0200, Tomi Ollila  wrote:
> A new configuration key 'new.ignore' is used to determine which
> files and directories user wants not to be scanned as new mails.
> 
> Mark the corresponding test as no longer broken
> (test from id:"1328105573-4626-1-git-send-email-pie...@praet.org" ).
> 
> This work merges my previous attempts and Andreas Amann's work
> in id:"ylp7hi23mw8@tyndall.ie"
> 
> See notes in id:"20120202-new-ignore-1-git-send-email-...@iki.fi"
> ---
> 
> Whenever some already existing directory is added to the exclude list
> and the parent directory timestamp has not changed, notmuch new will not
> notice the directory has gone (as it still is there), user needs to 'touch'
> the parent directory before next 'notmuch new' no make notmuch notice.
> 
> 2012-01-26: could notmuch track mtime of the configuration file and if
> that changes, ignore mail directory timestamps ?
> 
> See previous notes in id:"20120131-new-ignore-1-git-send-email-...@iki.fi"
> 
>  notmuch-client.h |   10 ++
>  notmuch-config.c |   33 +++--
>  notmuch-new.c|   45 +
>  test/new |1 -
>  4 files changed, 74 insertions(+), 15 deletions(-)
> 
> diff --git a/notmuch-client.h b/notmuch-client.h
> index e0eb594..26153df 100644
> --- a/notmuch-client.h
> +++ b/notmuch-client.h
> @@ -245,11 +245,21 @@ notmuch_config_set_user_other_email (notmuch_config_t 
> *config,
>  const char **
>  notmuch_config_get_new_tags (notmuch_config_t *config,
>size_t *length);
> +

Nitpick: unrelated change.

>  void
>  notmuch_config_set_new_tags (notmuch_config_t *config,
>const char *new_tags[],
>size_t length);
>  
> +const char **
> +notmuch_config_get_new_ignore (notmuch_config_t *config,
> +size_t *length);
> +
> +void
> +notmuch_config_set_new_ignore (notmuch_config_t *config,
> +const char *new_ignore[],
> +size_t length);
> +
>  notmuch_bool_t
>  notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);
>  
> diff --git a/notmuch-config.c b/notmuch-config.c
> index a124e34..1f01004 100644
> --- a/notmuch-config.c
> +++ b/notmuch-config.c
> @@ -44,7 +44,10 @@ static const char new_config_comment[] =
>  " The following options are supported here:\n"
>  "\n"
>  "\ttags  A list (separated by ';') of the tags that will be\n"
> -"\t  added to all messages incorporated by \"notmuch new\".\n";
> +"\t  added to all messages incorporated by \"notmuch new\".\n"
> +"\n"
> +"\tignoreA list (separated by ';') of file and directory names\n"
> +"\t  that will not be searched for messages by \"notmuch new\".\n";

Do I understand the code correctly, the ignore list must contain file
and directory names without (absolute or relative) paths? And that there
is no way to exclude only the subdirectory "foo" within directory "foo",
because they would both get ignored?

I don't see this as a bad thing, not at all. This keeps things nice and
simple, it just needs proper documentation.

>  
>  static const char user_config_comment[] =
>  " User configuration\n"
> @@ -105,6 +108,8 @@ struct _notmuch_config {
>  size_t user_other_email_length;
>  const char **new_tags;
>  size_t new_tags_length;
> +const char **new_ignore;
> +size_t new_ignore_length;
>  notmuch_bool_t maildir_synchronize_flags;
>  const char **search_exclude_tags;
>  size_t search_exclude_tags_length;
> @@ -264,6 +269,8 @@ notmuch_config_open (void *ctx,
>  config->user_other_email_length = 0;
>  config->new_tags = NULL;
>  config->new_tags_length = 0;
> +config->new_ignore = NULL;
> +config->new_ignore_length = 0;
>  config->maildir_synchronize_flags = TRUE;
>  config->search_exclude_tags = NULL;
>  config->search_exclude_tags_length = 0;
> @@ -361,6 +368,10 @@ notmuch_config_open (void *ctx,
>   notmuch_config_set_new_tags (config, tags, 2);
>  }
>  
> +if (notmuch_config_get_new_ignore (config, &tmp) == NULL) {
> + notmuch_config_set_new_ignore (config, NULL, 0);
> +}
> +
> 

Re: [PATCH] emacs: Fix a notmuch-print.el compiler warning.

2012-02-02 Thread Tomi Ollila
On Wed, 25 Jan 2012 09:24:46 +, David Edmondson  wrote:
> On Wed, 25 Jan 2012 11:19:30 +0200, Tomi Ollila  wrote:
> > On Wed, 25 Jan 2012 08:52:15 +, David Edmondson  wrote:
> > > `notmuch-show-get-prop' should be declared.
> > > ---
> > 
> > How 'bout 
> > 
> > (require 'notmuch-lib)
> > 
> > and put that declare-function there ?
> > 
> > So that when declaration gets checked when notmuch-show defuns it 
> 
> That doesn't work, as I recall. A `declare-function' in a `require'd
> file has no effect - the compiler will still complain.

Ok

+1

I (might) check how check-declare can be used here...


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


Re: [RFC][PATCH] emacs: Provide scaffolding so that the new `shr' HTML renderer can run.

2012-02-02 Thread Chris Gray
On Mon, 23 Jan 2012 15:43:08 +0100, Florian Friesdorf  wrote:
> With notmuch-0.11 (require 'gnus-art') "fixes" the void
> gnus-inhibit-images error.

This is true, though as Aaron Ecay pointed out in the discussion of this
patch, it does bring in all of gnus.  My current workaround to the bug
of gnus-inhibit-images being void is to load gnus, so that's just as
bad, but it would be great if we didn't have to do that.

> emacs git master has a fix for that, so you seem to have got through.

I got a notification that it went in the gnus git repo a couple of weeks
ago, so it is nice to know that it has been propagated to the emacs repo
as well.

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


Re: ignore folders patch?

2012-02-02 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.oll...@iki.fi"

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

> Cheers,
> Fabio

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


Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-02-02 Thread Antoine Beaupré
On Tue, 17 Jan 2012 23:44:46 +, Mark Walters  
wrote:
> Define a keymap for attachment buttons to allow multiple actions.
> Define 3 possible actions:
> save attachment: exactly as currently,
> view attachment: uses mailcap entry,
> view attachment with user chosen program
> 
> Keymap on a button is: s for save, v for view and o for view with
> other program. Default (i.e. enter or mouse button) is save but this
> is configurable in notmuch customize.
> 
> One implementation detail: the view attachment function forces all
> attachments to be "displayed" using mailcap even if emacs could
> display them itself. Thus, for example, text/html appears in a browser
> and text/plain asks whether to save (on a standard debian setup)

This works pretty much as advertised, +1 from me, good work.

A.

-- 
C'est trop facile quand les guerres sont finies
D'aller gueuler que c'était la dernière
Amis bourgeois vous me faites envie
Ne voyez vous pas donc point vos cimetières?
- Jaques Brel


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


Re: on deleting messages

2012-02-02 Thread Antoine Beaupré
Hi Jamie!

I have taken the time to test those patches and those in the other
thread[1], and I like it! I was able to run all tests with the patches
applied and I am now running them alongside with most recent master
gd51b784 and Mark Walter's attachment buttons patch[2].

So I support those patches and hope they get in. The only issue I could
find was that I have the reflex of hitting A (capital a) instead of just
"a" in the search view because that's the key i hit in the show
view... but that's probably something i should get used to.

If something pops up I'll let you know!

A.

[1] id:"1325975294-646-2-git-send-email-jroll...@finestructure.net"
[2] id:"1326843886-18387-1-git-send-email-markwalters1...@gmail.com"

-- 
Antoine Beaupré +++ Réseau Koumbit Networks +++ +1.514.387.6262 #208



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


[patch] notmuch-addresses.py fix UnicodeDecodeError

2012-02-02 Thread Joshua Ismael Haase Hernandez
Hi there.

I am using notmuch and notmuch-adresses.py for adress completion. My
native language is spanish and so most of my contact names contain
accents or 'ñ', so python script failed for them.

I attach the fix, sorry about emacs blank spaces cleanup.



pgpnsxtfifIon.pgp
Description: PGP signature
diff --git a/notmuch_addresses.py b/notmuch_addresses.py
index 74a743c..866b327 100755
--- a/notmuch_addresses.py
+++ b/notmuch_addresses.py
@@ -15,7 +15,7 @@
 ## GNU General Public License for more details.
 
 ## NOTE: This script requires the notmuch python bindings.
-  
+
 import notmuch
 import ConfigParser
 import optparse
@@ -43,7 +43,7 @@ class EmailsWithNames(object):
 as a list email addresses (with or without best-choice real
 names), sorted by frequency.
 """
-
+
 def __init__(self):
 self.emails = {}
 
@@ -92,7 +92,7 @@ class EmailsWithNames(object):
 return names[1]
 
 def sorted_email_list(self):
-return sorted(self.emails.keys(), 
+return sorted(self.emails.keys(),
   key=self.email_freq,
   reverse=True)
 
@@ -105,7 +105,7 @@ class NotmuchAddressMatcher(object):
 """A simple address matcher, based on information information from
 the user's $HOME/.notmuch-config file.
 """
-
+
 def __init__(self, query_name, match_function=None):
 """
 """
@@ -167,15 +167,15 @@ class NotmuchAddressMatcher(object):
 full_name = addr[0]
 split_names = full_name.split(" ")
 mail = addr[1]
-if (len([name for name in split_names 
+if (len([name for name in split_names
  if self.match_function(name)]) > 0
-or 
+or
 self.match_function(full_name)
-or 
+or
 self.match_function(mail)):
-
+
 emails.add_email_and_name(mail, addr[0])
- 
+
 self.matches = emails.sorted_email_and_names_list()
 
 if __name__ == '__main__':
@@ -187,4 +187,4 @@ if __name__ == '__main__':
 matcher = NotmuchAddressMatcher(name)
 matcher.generate_matches()
 
-for elem in matcher.matches: print (elem)
+for elem in matcher.matches: print (elem.encode('utf-8'))
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


BiDi

2012-02-02 Thread Clint Adams
I just received an email in RTL script and it was rendered incorrectly
in the emacs interface.  Does anyone know what to do about this?
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Set "From" based on "To" when replying

2012-02-02 Thread Simon Campese
Dear Community,

I've got my own domain and when registering or shopping at some website,
I always use email addresses of the form "websiten...@mydomain.org", so
for example I use "ama...@mydomain.org" when shopping at amazon. The
reason for this is categorizing incoming mail on the one hand, and
immediately being able to spot the source of spam on the other hand. 

I would like to implement the following behaviour: When replying to a
mail that has "someth...@mydomain.org" in the "To"-header, I would like
to have the "From"-header of the reply to be automatically set to this
address. 

Is there some kind of reply-hook in notmuch where one could put an
appropriate function? 


Thank you very much for your help,

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


Re: Emacs: Crypto: How to get automatic encryption?

2012-02-02 Thread Antoine Beaupré
On Tue, 17 Jan 2012 09:19:51 +, David Edmondson  wrote:
> On Mon, 16 Jan 2012 23:48:30 -0500, Antoine Beaupré  
> wrote:
> > Jumping in here, I have modified the previously posted code here to
> > provide me with a more complete solution.
> 
> This looks good. I'll switch over to using it.

Awesome!

> > Code is attached. Obviously, those function names would change if they
> > would be to integrate into notmuch. ;)
> 
> I wondered about pushing to have notmuch do this by default. In general
> I like the idea, but it suffers if a recipient occasionally uses a mail
> client that does not support decryption (phone, PDA, webmail, ...).

Well, it your call: you can disable encryption on the fly by setting the
message to just signing...

I have also found out (to great pains) that it is kind of difficult to
*completely* disable signing or encrypting, as the send-hook will
happily add back the #secure line even if you remove it.

A workaround is to set "mode=none" in the #secure line manually. Maybe
C-c RET C-n could do that instead of just removing the line?

On Tue, 17 Jan 2012 15:39:52 +, David Edmondson  wrote:
> >(if (and force (re-search-forward "<#secure [> >]*>\n" nil t))
> >(replace-match "" nil nil))
> >;; If we can encrypt, do so, else just sign.
> >(if (or force (not (re-search-forward "<#secure [> >]*>\n" nil t)))
> 
> Is this second test for `force' necessary? If `force' is set then you'll
> remove the <#secure..> just above, so it will not be found here.

Yes, it is. If force is true, the search-forward will not be ran at
all. The idea here is that if we do not force (ie. if we're running in
the hook), we do not want to override the existing #secure tags, to
respect the users' choices.

Cheers,

A.

-- 
Antoine Beaupré +++ Réseau Koumbit Networks +++ +1.514.387.6262 #208

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


Re: Emacs: Crypto: How to get automatic encryption?

2012-02-02 Thread Antoine Beaupré
Jumping in here, I have modified the previously posted code here to
provide me with a more complete solution.

With the attach code, I can:

 * automatically encrypt mails if all recipients have a *valid* public
   key. The previous patch allowed encryption if a key existed but was
   revoked, which cause a weird UX issue where the user would be
   bothered with "No public key for..."

 * not have specify if i want to encrypt the mail or not: it is
   encrypted if possible

 * try to autodetect (by running the function directly) if the mail will
   be crypted and signed or just signed before sending

 * explicitely request the mail to be encrypted or just signed, if I
   want to, using the usual keybindings (ie. the existing #secure tags
   are respected)

So basically, this replaces the common hook:

(add-hook 'message-setup-hook 'mml-secure-sign-pgpmime)

with this:

(add-hook 'message-send-hook 'anarcat/message-set-encryption)

The rationale behind this technique is that the setup-hook runs when
recipients are not yet defined so it will always set the mail to be only
signed, even though your final recipients should be crypted. 

An alternative would be for notmuch to prompt the To: header before
setting up the buffer ("à la" Mutt), but I didn't feel like going that
way.

Code is attached. Obviously, those function names would change if they
would be to integrate into notmuch. ;)



notmuch-opportunistic.el
Description: application/emacs-lisp

Opportunistic encryption, here we go.

a.

-- 
Evil exists to glorify the good. Evil is negative good.
It is a relative term. Evil can be transmuted into good.
What is evil to one at one time,
becomes good at another time to somebody else.
- Sivananda


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


Please Update Current GLib Requirements For notmuch: - (glib-2.0 >= 2.14) + (glib-2.0 >= 2.22)

2012-02-02 Thread datapipe
I've just tried to compile notmuch, after having downloaded it a few
hours back, via: `git clone git://notmuchmail.org/git/notmuch`.
Unfortunately, even though I seem to have all needed dependencies in
place, during the build I ran into the following error:
lib/query.cc: In function 'int
_notmuch_threads_destructor(notmuch_threads_t*)':
lib/query.cc:311: error: 'g_array_unref' was not declared in this scope

Looking into this 'g_array_unref' function, I found that it should be
provided by glib, but it seems that it isn't even defined in any of the
header files installed by glib on this system (v2.20.3), although I did
find it within /usr/include/glib-2.0/glib/garray.h on a system with a
newer version (v2.24.2).  Looking into its documentation, I found the
following:
http://developer.gnome.org/glib/2.31/glib-Arrays.html#g-array-unref
And specifically note:
"g_array_ref ()
...
Since 2.22"

Now, unless I'm misinterpreting this, it seems to me that the
documentation is stating that the function has only been available since
glib v2.22...


--
Sub


---
DO NOT REPLY TO THIS MESSAGE, THIS ADDRESS IS NOT MONITORED
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2] emacs: add default value to notmuch-search-line-faces

2012-02-02 Thread Tomi Ollila
On Thu,  2 Feb 2012 16:58:41 +0200, Jani Nikula  wrote:
> Add default value to notmuch-search-line-faces to show "unread"
> messages in bold, and "flagged" messages in blue, to have some visual
> indication of important messages in search results. This should be
> helpful for new users.
> 
> "unread" tag is quite obvious, and handled specially both in the lib
> and emacs ui. "flagged" is synced to maildir F flag in the lib. If one
> syncs the maildir to IMAP, this also translates to corresponding IMAP
> flag. (This is "starred" in GMail and Android.)
> 
> Signed-off-by: Jani Nikula 
> ---

Works fine. +1

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


Re: [PATCH] test: make test_expect_equal_file() arguments flexible

2012-02-02 Thread Tomi Ollila
On Thu, 02 Feb 2012 14:33:56 +, David Edmondson  wrote:
> On Wed, 01 Feb 2012 09:24:32 -0800, Jameson Graef Rollins 
>  wrote:
> > If this is really a problem, I vote for 1.  In general, I am not in
> > favor of making the test suite more complicated than it needs to be.
> 
> After listening to the debate, I agree. The documentation should state
> that the order is 'expected actual' (or the other way around) and
> offenders should be shot on sight^W^W^Wfixed.

I've started to agree with Dmitry.

Why do something that computer can do -- to guide test writers to
give args in consistent order and provide suitable filenames.

Secondly as the output files are provided for human consumption
if there is consistent naming in expected output files helps 
developers getting parts of the big picture easier and finding 
right filenames easier.

... and the reviewers doesn't need to keep their plasma guns
handly.

Tomi

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


[PATCH] add support for user-specified files & directories to ignore

2012-02-02 Thread Tomi Ollila
A new configuration key 'new.ignore' is used to determine which
files and directories user wants not to be scanned as new mails.

Mark the corresponding test as no longer broken
(test from id:"1328105573-4626-1-git-send-email-pie...@praet.org" ).

This work merges my previous attempts and Andreas Amann's work
in id:"ylp7hi23mw8@tyndall.ie"

See notes in id:"20120202-new-ignore-1-git-send-email-...@iki.fi"
---

Whenever some already existing directory is added to the exclude list
and the parent directory timestamp has not changed, notmuch new will not
notice the directory has gone (as it still is there), user needs to 'touch'
the parent directory before next 'notmuch new' no make notmuch notice.

2012-01-26: could notmuch track mtime of the configuration file and if
that changes, ignore mail directory timestamps ?

See previous notes in id:"20120131-new-ignore-1-git-send-email-...@iki.fi"

 notmuch-client.h |   10 ++
 notmuch-config.c |   33 +++--
 notmuch-new.c|   45 +
 test/new |1 -
 4 files changed, 74 insertions(+), 15 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index e0eb594..26153df 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -245,11 +245,21 @@ notmuch_config_set_user_other_email (notmuch_config_t 
*config,
 const char **
 notmuch_config_get_new_tags (notmuch_config_t *config,
 size_t *length);
+
 void
 notmuch_config_set_new_tags (notmuch_config_t *config,
 const char *new_tags[],
 size_t length);
 
+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config,
+  size_t *length);
+
+void
+notmuch_config_set_new_ignore (notmuch_config_t *config,
+  const char *new_ignore[],
+  size_t length);
+
 notmuch_bool_t
 notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index a124e34..1f01004 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -44,7 +44,10 @@ static const char new_config_comment[] =
 " The following options are supported here:\n"
 "\n"
 "\ttagsA list (separated by ';') of the tags that will be\n"
-"\tadded to all messages incorporated by \"notmuch new\".\n";
+"\tadded to all messages incorporated by \"notmuch new\".\n"
+"\n"
+"\tignore  A list (separated by ';') of file and directory names\n"
+"\tthat will not be searched for messages by \"notmuch new\".\n";
 
 static const char user_config_comment[] =
 " User configuration\n"
@@ -105,6 +108,8 @@ struct _notmuch_config {
 size_t user_other_email_length;
 const char **new_tags;
 size_t new_tags_length;
+const char **new_ignore;
+size_t new_ignore_length;
 notmuch_bool_t maildir_synchronize_flags;
 const char **search_exclude_tags;
 size_t search_exclude_tags_length;
@@ -264,6 +269,8 @@ notmuch_config_open (void *ctx,
 config->user_other_email_length = 0;
 config->new_tags = NULL;
 config->new_tags_length = 0;
+config->new_ignore = NULL;
+config->new_ignore_length = 0;
 config->maildir_synchronize_flags = TRUE;
 config->search_exclude_tags = NULL;
 config->search_exclude_tags_length = 0;
@@ -361,6 +368,10 @@ notmuch_config_open (void *ctx,
notmuch_config_set_new_tags (config, tags, 2);
 }
 
+if (notmuch_config_get_new_ignore (config, &tmp) == NULL) {
+   notmuch_config_set_new_ignore (config, NULL, 0);
+}
+
 if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) {
if (is_new) {
const char *tags[] = { "deleted", "spam" };
@@ -504,7 +515,8 @@ _config_set_list (notmuch_config_t *config,
  const char *list[],
  size_t length, const char ***config_var )
 {
-g_key_file_set_string_list (config->key_file, group, name, list, length);
+g_key_file_set_string_list (config->key_file,
+   group, name, list, length);
 talloc_free (*config_var);
 *config_var = NULL;
 }
@@ -609,6 +621,14 @@ notmuch_config_get_new_tags (notmuch_config_t *config,   
size_t *length)
 &(config->new_tags_length), length);
 }
 
+const char **
+notmuch_config_get_new_ignore (notmuch_config_t *config, size_t *length)
+{
+return _config_get_list (config, "new", "ignore",
+&(config->new_ignore),
+&(config->new_ignore_length), length);
+}
+

[PATCH v2] emacs: add default value to notmuch-search-line-faces

2012-02-02 Thread Jani Nikula
Add default value to notmuch-search-line-faces to show "unread"
messages in bold, and "flagged" messages in blue, to have some visual
indication of important messages in search results. This should be
helpful for new users.

"unread" tag is quite obvious, and handled specially both in the lib
and emacs ui. "flagged" is synced to maildir F flag in the lib. If one
syncs the maildir to IMAP, this also translates to corresponding IMAP
flag. (This is "starred" in GMail and Android.)

Signed-off-by: Jani Nikula 
---
 emacs/notmuch.el |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 5fa239a..bbf0aec 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -688,7 +688,8 @@ This function advances the next thread when finished."
  (goto-char (point-min))
  (forward-line (1- notmuch-search-target-line
 
-(defcustom notmuch-search-line-faces nil
+(defcustom notmuch-search-line-faces '(("unread" :weight bold)
+  ("flagged" :foreground "blue"))
   "Tag/face mapping for line highlighting in notmuch-search.
 
 Here is an example of how to color search results based on tags.
-- 
1.7.5.4

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


Re: [PATCH] test: make test_expect_equal_file() arguments flexible

2012-02-02 Thread David Edmondson
On Wed, 01 Feb 2012 09:24:32 -0800, Jameson Graef Rollins 
 wrote:
> If this is really a problem, I vote for 1.  In general, I am not in
> favor of making the test suite more complicated than it needs to be.

After listening to the debate, I agree. The documentation should state
that the order is 'expected actual' (or the other way around) and
offenders should be shot on sight^W^W^Wfixed.


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


[PATCH v4 2/2] emacs: quote MML tags in replies

2012-02-02 Thread David Bremner
From: Aaron Ecay 

Emacs message-mode uses certain text strings to indicate how to attach
files to outgoing mail.  If these are present in the text of an email,
and a user is tricked into replying to the message, the user’s files
could be exposed.

Using point-max would include the signature in the quoting as well.
It would probably be fairly odd to want to put an MML tag in one’s
signature, but that doesn’t mean that we should break that usage.
---
 NEWS |   11 +++
 emacs/notmuch-mua.el |7 ++-
 test/emacs   |1 -
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 3d2c2a8..a089e67 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,17 @@ Fix error handling in python bindings.
   exceptions to indicate the error condition. Any subsequent calls
   into libnotmuch caused segmentation faults.
 
+Quote MML tags in replies
+
+  MML tags are text codes that Emacs uses to indicate attachments
+  (among other things) in messages being composed.  The Emacs
+  interface did not quote MML tags in the quoted text of a reply.
+  User could be tricked into replying to a maliciously formatted
+  message and not editing out the MML tags from the quoted text.  This
+  could lead to files from the user's machine being attached to the
+  outgoing message.  The Emacs interface now quotes these tags in
+  reply text, so that they do not effect outgoing messages.
+
 
 Notmuch 0.11 (2012-01-13)
 =
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7114e48..768b693 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -111,7 +111,12 @@ list."
 (insert body))
   (set-buffer-modified-p nil)
 
-  (message-goto-body))
+  (message-goto-body)
+  ;; Original message may contain (malicious) MML tags.  We must
+  ;; properly quote them in the reply.  Note that using `point-max'
+  ;; instead of `mark' here is wrong.  The buffer may include user's
+  ;; signature which should not be MML-quoted.
+  (mml-quote-region (point) (mark)))
 
 (defun notmuch-mua-forward-message ()
   (message-forward)
diff --git a/test/emacs b/test/emacs
index 2a2ce28..de100c5 100755
--- a/test/emacs
+++ b/test/emacs
@@ -274,7 +274,6 @@ EOF
 test_expect_equal_file OUTPUT EXPECTED
 
 test_begin_subtest "Quote MML tags in reply"
-test_subtest_known_broken
 message_id='test-emacs-mml-quot...@message.id'
 add_message [id]="$message_id" \
"[subject]='$test_subtest_name'" \
-- 
1.7.8.3

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


[PATCH v4 1/2] test: add tests for quoting of MML tags in replies

2012-02-02 Thread David Bremner
From: Aaron Ecay 

The test is broken at this time; the next commit will introduce a fix.
---
 test/emacs|   12 
 test/emacs.expected-output/quote-mml-in-reply |7 +++
 2 files changed, 19 insertions(+), 0 deletions(-)
 create mode 100644 test/emacs.expected-output/quote-mml-in-reply

diff --git a/test/emacs b/test/emacs
index f36718e..2a2ce28 100755
--- a/test/emacs
+++ b/test/emacs
@@ -273,6 +273,18 @@ On 01 Jan 2000 12:00:00 -, Notmuch Test Suite 
 w
 EOF
 test_expect_equal_file OUTPUT EXPECTED
 
+test_begin_subtest "Quote MML tags in reply"
+test_subtest_known_broken
+message_id='test-emacs-mml-quot...@message.id'
+add_message [id]="$message_id" \
+   "[subject]='$test_subtest_name'" \
+   '[body]="<#part disposition=inline>"'
+test_emacs "(let ((notmuch-fcc-dirs nil))
+ (notmuch-show \"id:$message_id\")
+ (notmuch-show-reply)
+ (test-output))"
+test_expect_equal_file OUTPUT "$EXPECTED/quote-mml-in-reply"
+
 test_begin_subtest "Save attachment from within emacs using 
notmuch-show-save-attachments"
 # save as archive to test that Emacs does not re-compress .gz
 test_emacs '(let ((standard-input "\"attachment1.gz\""))
diff --git a/test/emacs.expected-output/quote-mml-in-reply 
b/test/emacs.expected-output/quote-mml-in-reply
new file mode 100644
index 000..adec92a
--- /dev/null
+++ b/test/emacs.expected-output/quote-mml-in-reply
@@ -0,0 +1,7 @@
+From: Notmuch Test Suite 
+To: 
+Subject: Re: Quote MML tags in reply
+In-Reply-To: 
+--text follows this line--
+On Fri, 05 Jan 2001 15:43:57 +, Notmuch Test Suite 
 wrote:
+> <#!part disposition=inline>
-- 
1.7.8.3

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


[PATCH v6 8/8] emacs: A prefix argument to `notmuch-show' should invert the matching message behaviour.

2012-02-02 Thread David Edmondson
Allow the user to open a thread with inverted
`notmuch-show-only-matching-messages' behaviour using a prefix
argument.
---
 emacs/notmuch-show.el |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index ae7af02..e9aa4e7 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1024,8 +1024,11 @@ function is used."
 ;; buffer.
 (setq notmuch-show-process-crypto notmuch-crypto-process-mime)
 ;; Set the default value for
-;; `notmuch-show-elide-non-matching-messages' in this buffer.
+;; `notmuch-show-elide-non-matching-messages' in this buffer. If
+;; there is a prefix argument, invert the default.
 (setq notmuch-show-elide-non-matching-messages 
notmuch-show-only-matching-messages)
+(if current-prefix-arg
+   (setq notmuch-show-elide-non-matching-messages (not 
notmuch-show-elide-non-matching-messages)))
 
 (setq notmuch-show-thread-id thread-id
  notmuch-show-parent-buffer parent-buffer
-- 
1.7.8.3

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


[PATCH v6 5/8] emacs: Optionally retain the state of the buffer during `notmuch-show-refresh-view'.

2012-02-02 Thread David Edmondson
With an argument, record and reply the state of the buffer during
`notmuch-show-refresh-view'.

In this context, "state" is defined as:
 - the open/closed state of each message,
 - the current message.

Traditional use of refresh with the = key does not retain the
state. The recently introduced toggle commands ($, !, < and >) do
retain the state.
---
 emacs/notmuch-show.el |   56 ++---
 1 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 8d318c9..1b31166 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -938,7 +938,7 @@ current buffer, if possible."
   (message (if notmuch-show-process-crypto
   "Processing cryptographic MIME parts."
 "Not processing cryptographic MIME parts."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))
 
 (defun notmuch-show-toggle-elide-non-matching ()
   "Toggle the display of non-matching messages."
@@ -947,7 +947,7 @@ current buffer, if possible."
   (message (if notmuch-show-elide-non-matching-messages
   "Showing matching messages only."
 "Showing all messages."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))
 
 (defun notmuch-show-toggle-thread-indentation ()
   "Toggle the indentation of threads."
@@ -956,7 +956,7 @@ current buffer, if possible."
   (message (if notmuch-show-indent-content
   "Content is indented."
 "Content is not indented."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))
 
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
@@ -1060,14 +1060,54 @@ function is used."
 
 (notmuch-show-mark-read)))
 
-(defun notmuch-show-refresh-view ()
+(defun notmuch-show-capture-state ()
+  "Capture the state of the current buffer.
+
+This includes:
+ - the list of open messages,
+ - the current message."
+  (list (notmuch-show-get-message-id) 
(notmuch-show-get-message-ids-for-open-messages)))
+
+(defun notmuch-show-apply-state (state)
+  "Apply STATE to the current buffer.
+
+This includes:
+ - opening the messages previously opened,
+ - closing all other messages,
+ - moving to the correct current message."
+  (let ((current (car state))
+   (open (cadr state)))
+
+;; Open those that were open.
+(goto-char (point-min))
+(loop do (notmuch-show-message-visible 
(notmuch-show-get-message-properties)
+  (member 
(notmuch-show-get-message-id) open))
+ until (not (notmuch-show-goto-message-next)))
+
+;; Go to the previously open message.
+(goto-char (point-min))
+(unless (loop if (string= current (notmuch-show-get-message-id))
+ return t
+ until (not (notmuch-show-goto-message-next)))
+  (goto-char (point-min))
+  (message "Previously current message not found."))
+(notmuch-show-message-adjust)))
+
+(defun notmuch-show-refresh-view (&optional retain-state)
   "Refresh the current view.
 
-Refreshes the current view, observing changes in cryptographic preferences."
+Refreshes the current view, observing changes in display
+preferences. If RETAIN-STATE is non-nil then the state of the
+buffer is stored and re-applied after the refresh."
   (interactive)
-  (let ((inhibit-read-only t))
-(erase-buffer))
-  (notmuch-show-worker))
+  (let ((inhibit-read-only t)
+   state)
+(if retain-state
+   (setq state (notmuch-show-capture-state)))
+(erase-buffer)
+(notmuch-show-worker)
+(if state
+   (notmuch-show-apply-state state
 
 (defvar notmuch-show-stash-map
   (let ((map (make-sparse-keymap)))
-- 
1.7.8.3

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


[PATCH v6 7/8] emacs: Add `notmuch-show-only-matching-messages'.

2012-02-02 Thread David Edmondson
Allow the user to choose that only matching messages are shown by
default.
---
 emacs/notmuch-show.el |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 895feb5..ae7af02 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -125,6 +125,11 @@ indentation."
 (const :tag "View interactively"
notmuch-show-interactively-view-part)))
 
+(defcustom notmuch-show-only-matching-messages nil
+  "Only matching messages are shown by default."
+  :type 'boolean
+  :group 'notmuch-show)
+
 (defvar notmuch-show-thread-id nil)
 (make-variable-buffer-local 'notmuch-show-thread-id)
 (put 'notmuch-show-thread-id 'permanent-local t)
@@ -1018,6 +1023,9 @@ function is used."
 ;; Set the default value for `notmuch-show-process-crypto' in this
 ;; buffer.
 (setq notmuch-show-process-crypto notmuch-crypto-process-mime)
+;; Set the default value for
+;; `notmuch-show-elide-non-matching-messages' in this buffer.
+(setq notmuch-show-elide-non-matching-messages 
notmuch-show-only-matching-messages)
 
 (setq notmuch-show-thread-id thread-id
  notmuch-show-parent-buffer parent-buffer
-- 
1.7.8.3

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


[PATCH v6 6/8] emacs: Check that the parent buffer is alive before using it.

2012-02-02 Thread David Edmondson
---
 emacs/notmuch-show.el |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 1b31166..895feb5 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1671,7 +1671,7 @@ added."
   (interactive "P")
   (let ((parent-buffer notmuch-show-parent-buffer))
 (notmuch-kill-this-buffer)
-(when parent-buffer
+(when (buffer-live-p parent-buffer)
   (switch-to-buffer parent-buffer)
   (notmuch-search-next-thread)
   (if show-next
-- 
1.7.8.3

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


[PATCH v6 2/8] emacs: Allow `notmuch-show-mode' to display only matching messages.

2012-02-02 Thread David Edmondson
The current behaviour (all messages shown, non-matching collapsed)
is retained as the default. Type '!' to switch to showing only
the matching messages - non-matching messages are not available.
'!' will switch back to showing everything.
---
 emacs/notmuch-show.el |   18 +-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b6329d2..df81cd1 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -141,6 +141,10 @@ indentation."
 (make-variable-buffer-local 'notmuch-show-process-crypto)
 (put 'notmuch-show-process-crypto 'permanent-local t)
 
+(defvar notmuch-show-elide-non-matching-messages nil)
+(make-variable-buffer-local 'notmuch-show-elide-non-matching-messages)
+(put 'notmuch-show-elide-non-matching-messages 'permanent-local t)
+
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
@@ -928,11 +932,22 @@ current buffer, if possible."
 "Not processing cryptographic MIME parts."))
   (notmuch-show-refresh-view))
 
+(defun notmuch-show-toggle-elide-non-matching ()
+  "Toggle the display of non-matching messages."
+  (interactive)
+  (setq notmuch-show-elide-non-matching-messages (not 
notmuch-show-elide-non-matching-messages))
+  (message (if notmuch-show-elide-non-matching-messages
+  "Showing matching messages only."
+"Showing all messages."))
+  (notmuch-show-refresh-view))
+
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
   (let ((msg (car tree))
(replies (cadr tree)))
-(notmuch-show-insert-msg msg depth)
+(if (or (not notmuch-show-elide-non-matching-messages)
+   (plist-get msg :match))
+   (notmuch-show-insert-msg msg depth))
 (notmuch-show-insert-thread replies (1+ depth
 
 (defun notmuch-show-insert-thread (thread depth)
@@ -1086,6 +1101,7 @@ Refreshes the current view, observing changes in 
cryptographic preferences."
(define-key map (kbd "M-RET") 'notmuch-show-open-or-close-all)
(define-key map (kbd "RET") 'notmuch-show-toggle-message)
(define-key map "#" 'notmuch-show-print-message)
+   (define-key map "!" 'notmuch-show-toggle-elide-non-matching)
(define-key map "$" 'notmuch-show-toggle-process-crypto)
map)
   "Keymap for \"notmuch show\" buffers.")
-- 
1.7.8.3

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


[PATCH v6 3/8] emacs: Allow the indentation of content to be toggled.

2012-02-02 Thread David Edmondson
Very deeply indented content is sometimes difficult to
read (particular for something like patches). Allow the indentation of
the content to be toggled with '<'.

Indentation of the header lines is not affected, so it remains
possible to see the structure of the thread.
---
 emacs/notmuch-show.el |   26 ++
 1 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index df81cd1..a07a44a 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -145,6 +145,10 @@ indentation."
 (make-variable-buffer-local 'notmuch-show-elide-non-matching-messages)
 (put 'notmuch-show-elide-non-matching-messages 'permanent-local t)
 
+(defvar notmuch-show-indent-content t)
+(make-variable-buffer-local 'notmuch-show-indent-content)
+(put 'notmuch-show-indent-content 'permanent-local t)
+
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
@@ -255,10 +259,12 @@ operation on the contents of the current buffer."
 (all (buffer-substring (notmuch-show-message-top)
(notmuch-show-message-bottom)))
 
-(props (notmuch-show-get-message-properties)))
+(props (notmuch-show-get-message-properties))
+(indenting notmuch-show-indent-content))
 (with-temp-buffer
   (insert all)
-  (indent-rigidly (point-min) (point-max) (- depth))
+  (if indenting
+ (indent-rigidly (point-min) (point-max) (- depth)))
   ;; Remove the original header.
   (goto-char (point-min))
   (re-search-forward "^$" (point-max) nil)
@@ -886,7 +892,8 @@ current buffer, if possible."
 (setq notmuch-show-previous-subject bare-subject)
 
 (setq body-start (point-marker))
-(notmuch-show-insert-body msg (plist-get msg :body) depth)
+(notmuch-show-insert-body msg (plist-get msg :body)
+ (if notmuch-show-indent-content depth 0))
 ;; Ensure that the body ends with a newline.
 (unless (bolp)
   (insert "\n"))
@@ -894,7 +901,8 @@ current buffer, if possible."
 (setq content-end (point-marker))
 
 ;; Indent according to the depth in the thread.
-(indent-rigidly content-start content-end (* 
notmuch-show-indent-messages-width depth))
+(if notmuch-show-indent-content
+   (indent-rigidly content-start content-end (* 
notmuch-show-indent-messages-width depth)))
 
 (setq message-end (point-max-marker))
 
@@ -941,6 +949,15 @@ current buffer, if possible."
 "Showing all messages."))
   (notmuch-show-refresh-view))
 
+(defun notmuch-show-toggle-thread-indentation ()
+  "Toggle the indentation of threads."
+  (interactive)
+  (setq notmuch-show-indent-content (not notmuch-show-indent-content))
+  (message (if notmuch-show-indent-content
+  "Content is indented."
+"Content is not indented."))
+  (notmuch-show-refresh-view))
+
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
   (let ((msg (car tree))
@@ -1103,6 +1120,7 @@ Refreshes the current view, observing changes in 
cryptographic preferences."
(define-key map "#" 'notmuch-show-print-message)
(define-key map "!" 'notmuch-show-toggle-elide-non-matching)
(define-key map "$" 'notmuch-show-toggle-process-crypto)
+   (define-key map "<" 'notmuch-show-toggle-thread-indentation)
map)
   "Keymap for \"notmuch show\" buffers.")
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)
-- 
1.7.8.3

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


[no subject]

2012-02-02 Thread David Bremner
I rebased these against branch release (and copied a comment from
aaron's email), but the test fails there, as does the reply within emacs test.

FAIL   Reply within emacs
--- emacs.24.expected   2012-02-02 03:55:14.0 +
+++ emacs.24.output 2012-02-02 03:55:14.0 +
@@ -1,8 +1,4 @@
 From: Notmuch Test Suite 
-To: u...@example.com
-Subject: Re: Testing message sent via SMTP
-In-Reply-To: 
-Fcc: /home/bremner/software/upstream/notmuch/test/tmp.emacs/mail/sent
+To: 
+Subject: 
 --text follows this line--
-On 01 Jan 2000 12:00:00 -, Notmuch Test Suite 
 wrote:
-> This is a test that messages are sent via SMTP
*ERROR*: Wrong type argument: integer-or-marker-p, nil
 FAIL   Quote MML tags in reply
--- emacs.25.expected   2012-02-02 03:55:15.0 +
+++ emacs.25.output 2012-02-02 03:55:15.0 +
@@ -1,7 +1,4 @@
 From: Notmuch Test Suite 
 To: 
-Subject: Re: Quote MML tags in reply
-In-Reply-To: 
+Subject: 
 --text follows this line--
-On Fri, 05 Jan 2001 15:43:57 +, Notmuch Test Suite 
 wrote:
-> <#!part disposition=inline>
*ERROR*: Wrong type argument: integer-or-marker-p, nil


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


Re: [PATCH v2] emacs: globally replace non-branching "(if COND (progn ..." with "(when ..."

2012-02-02 Thread David Bremner
On Wed,  1 Feb 2012 14:50:00 +0100, Pieter Praet  wrote:
> Less code, same results, without sacrificing readability.
> 

pushed.

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


[PATCH v6 1/8] emacs: Rework crypto switch toggle.

2012-02-02 Thread David Edmondson
Re-work the existing crypto switch toggle to be based on a persistant
buffer-local variable.

To allow this, modify `notmuch-show-refresh-view' to erase and re-draw
in the current buffer rather than killing the current buffer and
creating a new one. (This will also allow more per-buffer behaviour in
future patches.)

Add a binding ('$') to toggle crypto processing of the current buffer
and remove the prefix argument approach that achieves a similar
result.
---
 emacs/notmuch-show.el |  126 
 emacs/notmuch.el  |7 +--
 2 files changed, 66 insertions(+), 67 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index de9421e..b6329d2 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -125,6 +125,22 @@ indentation."
 (const :tag "View interactively"
notmuch-show-interactively-view-part)))
 
+(defvar notmuch-show-thread-id nil)
+(make-variable-buffer-local 'notmuch-show-thread-id)
+(put 'notmuch-show-thread-id 'permanent-local t)
+
+(defvar notmuch-show-parent-buffer nil)
+(make-variable-buffer-local 'notmuch-show-parent-buffer)
+(put 'notmuch-show-parent-buffer 'permanent-local t)
+
+(defvar notmuch-show-query-context nil)
+(make-variable-buffer-local 'notmuch-show-query-context)
+(put 'notmuch-show-query-context 'permanent-local t)
+
+(defvar notmuch-show-process-crypto nil)
+(make-variable-buffer-local 'notmuch-show-process-crypto)
+(put 'notmuch-show-process-crypto 'permanent-local t)
+
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
@@ -411,14 +427,11 @@ message at DEPTH in the current thread."
 
 (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body)
   (declare (indent 2))
-  (let ((process-crypto (make-symbol "process-crypto")))
-`(let ((,process-crypto notmuch-show-process-crypto))
-   (with-temp-buffer
-(setq notmuch-show-process-crypto ,process-crypto)
-;; Always acquires the part via `notmuch part', even if it is
-;; available in the JSON output.
-(insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
-,@body
+  `(with-temp-buffer
+ ;; Always acquires the part via `notmuch part', even if it is
+ ;; available in the JSON output.
+ (insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
+ ,@body))
 
 (defun notmuch-show-save-part (message-id nth &optional filename content-type)
   (notmuch-with-temp-part-buffer message-id nth
@@ -600,7 +613,7 @@ current buffer, if possible."
   (sigstatus (car (plist-get part :sigstatus
  (notmuch-crypto-insert-sigstatus-button sigstatus from))
   ;; if we're not adding sigstatus, tell the user how they can get it
-  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic mime parts.")))
+  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic MIME parts.")))
 
   (let ((inner-parts (plist-get part :content))
(start (point)))
@@ -626,7 +639,7 @@ current buffer, if possible."
 (sigstatus (car (plist-get part :sigstatus
(notmuch-crypto-insert-sigstatus-button sigstatus from
   ;; if we're not adding encstatus, tell the user how they can get it
-  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic mime parts.")))
+  (button-put button 'help-echo "Set notmuch-crypto-process-mime to 
process cryptographic MIME parts.")))
 
   (let ((inner-parts (plist-get part :content))
(start (point)))
@@ -753,8 +766,6 @@ current buffer, if possible."
 
 ;; Helper for parts which are generally not included in the default
 ;; JSON output.
-;; Uses the buffer-local variable notmuch-show-process-crypto to
-;; determine if parts should be decrypted first.
 (defun notmuch-show-get-bodypart-internal (message-id part-number)
   (let ((args '("show" "--format=raw"))
(part-arg (format "--part=%s" part-number)))
@@ -908,6 +919,15 @@ current buffer, if possible."
 ;; criteria.
 (notmuch-show-message-visible msg (plist-get msg :match
 
+(defun notmuch-show-toggle-process-crypto ()
+  "Toggle the processing of cryptographic MIME parts."
+  (interactive)
+  (setq notmuch-show-process-crypto (not notmuch-show-process-crypto))
+  (message (if notmuch-show-process-crypto
+  "Processing cryptographic MIME parts."
+"Not processing cryptographic MIME parts."))
+  (notmuch-show-refresh-view))
+
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
   (let ((msg (car tree))
@@ -923,15 +943,6 @@ current buffer, if possible."
   "Insert the forest of threads FOREST."
   (mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))
 
-(defvar notmuch-show-thread-id

[PATCH v6 4/8] emacs: Add a binding (t) to toggle the truncation of long lines.

2012-02-02 Thread David Edmondson
---
 emacs/notmuch-show.el |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index a07a44a..8d318c9 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1121,6 +1121,7 @@ Refreshes the current view, observing changes in 
cryptographic preferences."
(define-key map "!" 'notmuch-show-toggle-elide-non-matching)
(define-key map "$" 'notmuch-show-toggle-process-crypto)
(define-key map "<" 'notmuch-show-toggle-thread-indentation)
+   (define-key map "t" 'toggle-truncate-lines)
map)
   "Keymap for \"notmuch show\" buffers.")
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)
-- 
1.7.8.3

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


  1   2   >