[PATCH v4 07/11] lib: added interface notmuch_thread_get_flag_messages
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
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.
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.
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
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
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
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
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
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.
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
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.
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.
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
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.
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
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
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
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
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
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
--- 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.
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
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
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
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
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
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
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.
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.
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
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
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.
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
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
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.
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
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
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.
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'.
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.
--- 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'.
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.
--- 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.
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.
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.
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
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
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.
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
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
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
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
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
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
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
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.
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.
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
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.
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
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
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
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
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
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
--- 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.
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
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
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
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
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
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.
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.
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?
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
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
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
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
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
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?
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?
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)
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
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
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
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
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
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
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
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.
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'.
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'.
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.
--- 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.
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.
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]
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 ..."
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.
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.
--- 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