[RFC][PATCH] tags_to_maildir_flags: Add option to not move messages from "new/" to "cur/"

Louis Rilling l.rilling at av7.net
Thu Jun 23 08:36:06 PDT 2011


notmuch_message_tags_to_maildir_flags() moves messages from maildir directory
"new/" to maildir directory "cur/", which makes messages lose their "new" status
in the MUA. However some users want to keep this "new" status after, for
instance, an auto-tagging of new messages.

This patch introduces notmuch_message_tags_to_maildir_flags_preserve(), which
does the same job as notmuch_message_tags_to_maildir_flags() except moving
from "maildir "new/" to maildir "cur/". A new option "preserve_new" is
introduced in "[maildir]" section of .notmuch-config, so that users can
configure whether commands "notmuch tag" and "notmuch restore" preserve the
"new" status or not.

Signed-off-by: Louis Rilling <l.rilling at av7.net>
---
Hi,

I'm in the process of using notmuch, but the issue "addressed" by this patch
would make me change my habits a bit too fast. I use the "new" status for
quickly checking (often without reading) which emails I just received,
implementing some kind of context/mood/daytime-dependent quick filtering. I'd
also like to run a pre-tagging script automatically when synchronizing
periodically (and automatically too) my mailboxes. But the current behavior of
"notmuch tag" makes me lose my quick filtering ability.

This patch is mostly written for discussion. It is certainly not polished (API,
ABI, bindings) and not tested at all. In particular, I know that there are some
plans to customize flags synchronization, but I don't know how the library API
could/should be impacted.

Thanks for your comments!

Louis


 lib/message.cc    |   33 +++++++++++++++++++++++++--------
 lib/notmuch.h     |    7 +++++++
 notmuch-client.h  |    7 +++++++
 notmuch-config.c  |   35 ++++++++++++++++++++++++++++++++++-
 notmuch-restore.c |   10 ++++++++--
 notmuch-tag.c     |   10 ++++++++--
 6 files changed, 89 insertions(+), 13 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 4b59fa9..c6c4160 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -1130,7 +1130,8 @@ static char*
 _new_maildir_filename (void *ctx,
 		       const char *filename,
 		       const char *flags_to_set,
-		       const char *flags_to_clear)
+		       const char *flags_to_clear,
+		       bool preserve_new)
 {
     const char *info, *flags;
     unsigned int flag, last_flag;
@@ -1211,16 +1212,19 @@ _new_maildir_filename (void *ctx,
     }
     *s = '\0';
 
-    /* If message is in new/ move it under cur/. */
-    dir = (char *) _filename_is_in_maildir (filename_new);
-    if (dir && STRNCMP_LITERAL (dir, "new/") == 0)
-	memcpy (dir, "cur/", 4);
+    if (!preserve_new) {
+	/* If message is in new/ move it under cur/. */
+	dir = (char *) _filename_is_in_maildir (filename_new);
+	if (dir && STRNCMP_LITERAL (dir, "new/") == 0)
+	    memcpy (dir, "cur/", 4);
+    }
 
     return filename_new;
 }
 
-notmuch_status_t
-notmuch_message_tags_to_maildir_flags (notmuch_message_t *message)
+static notmuch_status_t
+_notmuch_message_tags_to_maildir_flags (notmuch_message_t *message,
+					bool preserve_new)
 {
     notmuch_filenames_t *filenames;
     const char *filename;
@@ -1240,7 +1244,8 @@ notmuch_message_tags_to_maildir_flags (notmuch_message_t *message)
 	    continue;
 
 	filename_new = _new_maildir_filename (message, filename,
-					      to_set, to_clear);
+					      to_set, to_clear,
+					      preserve_new);
 	if (filename_new == NULL)
 	    continue;
 
@@ -1281,6 +1286,18 @@ notmuch_message_tags_to_maildir_flags (notmuch_message_t *message)
 }
 
 notmuch_status_t
+notmuch_message_tags_to_maildir_flags (notmuch_message_t *message)
+{
+    _notmuch_message_tags_to_maildir_flags(message, false);
+}
+
+notmuch_status_t
+notmuch_message_tags_to_maildir_flags_preserve (notmuch_message_t *message)
+{
+    _notmuch_message_tags_to_maildir_flags(message, true);
+}
+
+notmuch_status_t
 notmuch_message_remove_all_tags (notmuch_message_t *message)
 {
     notmuch_private_status_t private_status;
diff --git a/lib/notmuch.h b/lib/notmuch.h
index e508309..eeddc17 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -978,6 +978,13 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message);
  */
 notmuch_status_t
 notmuch_message_tags_to_maildir_flags (notmuch_message_t *message);
+/* Rename message filename(s) to encode tags as maildir flags, without moving from new/ to cur/
+ *
+ * Same as notmuch_message_tags_to_maildir_flags, but messages living in
+ * directory "new" are not moved to neighboring directory "cur".
+ */
+notmuch_status_t
+notmuch_message_tags_to_maildir_flags_preserve (notmuch_message_t *message);
 
 /* Freeze the current state of 'message' within the database.
  *
diff --git a/notmuch-client.h b/notmuch-client.h
index 63be337..2372fe6 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -235,6 +235,13 @@ notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,
 					      notmuch_bool_t synchronize_flags);
 
 notmuch_bool_t
+notmuch_config_get_maildir_preserve_new (notmuch_config_t *config);
+
+void
+notmuch_config_set_maildir_preserve_new (notmuch_config_t *config,
+					 notmuch_bool_t preserve_new);
+
+notmuch_bool_t
 debugger_is_active (void);
 
 #endif
diff --git a/notmuch-config.c b/notmuch-config.c
index 6e4c5c4..5ef5f44 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -81,7 +81,14 @@ static const char maildir_config_comment[] =
     "\n"
     "\tThe \"notmuch new\" command will notice flag changes in filenames\n"
     "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n"
-    "\tcommands will notice tag changes and update flags in filenames\n";
+    "\tcommands will notice tag changes and update flags in filenames\n"
+    "\n"
+    "\tpreserve_new           Valid values are true and false.\n"
+    "\n"
+    "\tThis setting has only effects if synchronize_flags is set to true.\n"
+    "\tIf true, the \"notmuch tag\" and \"notmuch restore\" commands will\n"
+    "\tpreserve the maildir \"new\" status of messages. If false, all updated\n"
+    "\tmessages lose their \"new\" status.\n";
 
 struct _notmuch_config {
     char *filename;
@@ -95,6 +102,7 @@ struct _notmuch_config {
     const char **new_tags;
     size_t new_tags_length;
     notmuch_bool_t maildir_synchronize_flags;
+    notmuch_bool_t maildir_preserve_new;
 };
 
 static int
@@ -251,6 +259,7 @@ notmuch_config_open (void *ctx,
     config->new_tags = NULL;
     config->new_tags_length = 0;
     config->maildir_synchronize_flags = TRUE;
+    config->maildir_preserve_new = FALSE;
 
     if (! g_key_file_load_from_file (config->key_file,
 				     config->filename,
@@ -353,6 +362,15 @@ notmuch_config_open (void *ctx,
 	g_error_free (error);
     }
 
+    error = NULL;
+    config->maildir_preserve_new =
+	g_key_file_get_boolean (config->key_file,
+				"maildir", "preserve_new", &error);
+    if (error) {
+	notmuch_config_set_maildir_preserve_new (config, FALSE);
+	g_error_free (error);
+    }
+
     /* Whenever we know of configuration sections that don't appear in
      * the configuration file, we add some comments to help the user
      * understand what can be done. */
@@ -764,3 +782,18 @@ notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,
 			    "maildir", "synchronize_flags", synchronize_flags);
     config->maildir_synchronize_flags = synchronize_flags;
 }
+
+notmuch_bool_t
+notmuch_config_get_maildir_preserve_new (notmuch_config_t *config)
+{
+    return config->maildir_preserve_new;
+}
+
+void
+notmuch_config_set_maildir_preserve_new (notmuch_config_t *config,
+					 notmuch_bool_t preserve_new)
+{
+    g_key_file_set_boolean (config->key_file,
+			    "maildir", "preserve_new", preserve_new);
+    config->maildir_preserve_new = preserve_new;
+}
diff --git a/notmuch-restore.c b/notmuch-restore.c
index f095f64..620a1f2 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -26,6 +26,7 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
     notmuch_config_t *config;
     notmuch_database_t *notmuch;
     notmuch_bool_t synchronize_flags;
+    notmuch_bool_t preserve_new;
     FILE *input;
     char *line = NULL;
     size_t line_size;
@@ -43,6 +44,7 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
 	return 1;
 
     synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
+    preserve_new = notmuch_config_get_maildir_preserve_new (config);
 
     if (argc) {
 	input = fopen (argv[0], "r");
@@ -134,8 +136,12 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
 
 	notmuch_message_thaw (message);
 
-	if (synchronize_flags)
-	    notmuch_message_tags_to_maildir_flags (message);
+	if (synchronize_flags) {
+	    if (preserve_new)
+		notmuch_message_tags_to_maildir_flags_preserve (message);
+	    else
+		notmuch_message_tags_to_maildir_flags (message);
+	}
 
       NEXT_LINE:
 	if (message)
diff --git a/notmuch-tag.c b/notmuch-tag.c
index 6204ae3..c36c3c9 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -44,6 +44,7 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
     notmuch_message_t *message;
     struct sigaction action;
     notmuch_bool_t synchronize_flags;
+    notmuch_bool_t preserve_new;
     int i;
 
     /* Setup our handler for SIGINT */
@@ -101,6 +102,7 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
 	return 1;
 
     synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
+    preserve_new = notmuch_config_get_maildir_preserve_new (config);
 
     query = notmuch_query_create (notmuch, query_string);
     if (query == NULL) {
@@ -128,8 +130,12 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
 
 	notmuch_message_thaw (message);
 
-	if (synchronize_flags)
-	    notmuch_message_tags_to_maildir_flags (message);
+	if (synchronize_flags) {
+	    if (preserve_new)
+		notmuch_message_tags_to_maildir_flags_preserve (message);
+	    else
+		notmuch_message_tags_to_maildir_flags (message);
+	}
 
 	notmuch_message_destroy (message);
     }
-- 
1.7.2.5



More information about the notmuch mailing list