When one of the source files for a message is changed on disk, renamed,
deleted or a new source file is added. A configurable changed tag is
is added. The tag can be configured under the option 'changed_tags' in
the [new] section, the default is none. Tests have been updated to
accept the new config option.

notmuch-setup now asks for a changed tag after the new tags question.

This could be useful for for example 'afew' to detect remote changes in
IMAP folders and update the FolderNameFilter to also add tags or remove
tags when a _existing_ message has been added to or removed from a
maildir.
---
 notmuch-client.h    |  8 ++++++++
 notmuch-config.c    | 42 ++++++++++++++++++++++++++++++++++++++----
 notmuch-new.c       | 34 +++++++++++++++++++++++++++++-----
 notmuch-setup.c     | 17 +++++++++++++++++
 test/T030-config.sh |  1 +
 test/T040-setup.sh  |  2 ++
 6 files changed, 95 insertions(+), 9 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index d110648..8b60645 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -314,6 +314,14 @@ notmuch_config_set_new_ignore (notmuch_config_t *config,
                               const char *new_ignore[],
                               size_t length);

+const char **
+notmuch_config_get_changed_tags (notmuch_config_t *config,
+                            size_t *length);
+void
+notmuch_config_set_changed_tags (notmuch_config_t *config,
+                            const char *changed_tags[],
+                            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 8d28653..5ea0635 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -51,7 +51,11 @@ static const char new_config_comment[] =
     "\n"
     "\t        NOTE: *Every* file/directory that goes by one of those\n"
     "\t        names will be ignored, independent of its depth/location\n"
-    "\t        in the mail store.\n";
+    "\t        in the mail store.\n"
+    "\n"
+    "\tchanged_tags A list (separated by ';') of tags that will be\n"
+    "\t added to messages where a one or more of its source files have\n"
+    "\t have been changed (added, renamed or deleted).\n";

 static const char user_config_comment[] =
     " User configuration\n"
@@ -111,10 +115,15 @@ struct _notmuch_config {
     char *user_primary_email;
     const char **user_other_email;
     size_t user_other_email_length;
+
     const char **new_tags;
     size_t new_tags_length;
     const char **new_ignore;
     size_t new_ignore_length;
+
+    const char **changed_tags;
+    size_t changed_tags_length;
+
     notmuch_bool_t maildir_synchronize_flags;
     const char **search_exclude_tags;
     size_t search_exclude_tags_length;
@@ -249,7 +258,7 @@ notmuch_config_open (void *ctx,
        fprintf (stderr, "Out of memory.\n");
        return NULL;
     }
-    
+
     talloc_set_destructor (config, notmuch_config_destructor);

     if (filename) {
@@ -273,6 +282,8 @@ notmuch_config_open (void *ctx,
     config->new_tags_length = 0;
     config->new_ignore = NULL;
     config->new_ignore_length = 0;
+    config->changed_tags = NULL;
+    config->changed_tags_length = 0;
     config->maildir_synchronize_flags = TRUE;
     config->search_exclude_tags = NULL;
     config->search_exclude_tags_length = 0;
@@ -373,6 +384,10 @@ notmuch_config_open (void *ctx,
        notmuch_config_set_new_ignore (config, NULL, 0);
     }

+    if (notmuch_config_get_changed_tags (config, &tmp) == NULL) {
+      notmuch_config_set_changed_tags (config, NULL, 0);
+    }
+
     if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) {
        if (config->is_new) {
            const char *tags[] = { "deleted", "spam" };
@@ -422,7 +437,7 @@ notmuch_config_open (void *ctx,
 }

 /* Close the given notmuch_config_t object, freeing all resources.
- * 
+ *
  * Note: Any changes made to the configuration are *not* saved by this
  * function. To save changes, call notmuch_config_save before
  * notmuch_config_close.
@@ -631,6 +646,14 @@ notmuch_config_get_new_ignore (notmuch_config_t *config, 
size_t *length)
                             &(config->new_ignore_length), length);
 }

+const char **
+notmuch_config_get_changed_tags (notmuch_config_t *config,   size_t *length)
+{
+    return _config_get_list (config, "new", "changed_tags",
+                            &(config->changed_tags),
+                            &(config->changed_tags_length), length);
+}
+
 void
 notmuch_config_set_user_other_email (notmuch_config_t *config,
                                     const char *list[],
@@ -658,6 +681,15 @@ notmuch_config_set_new_ignore (notmuch_config_t *config,
                     &(config->new_ignore));
 }

+void
+notmuch_config_set_changed_tags (notmuch_config_t *config,
+                                    const char *list[],
+                                    size_t length)
+{
+    _config_set_list (config, "new", "changed_tags", list, length,
+                    &(config->changed_tags));
+}
+
 const char **
 notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t 
*length)
 {
@@ -714,17 +746,19 @@ notmuch_config_command_get (notmuch_config_t *config, 
char *item)
     } else if (strcmp(item, "user.other_email") == 0) {
        const char **other_email;
        size_t i, length;
-       
+
        other_email = notmuch_config_get_user_other_email (config, &length);
        for (i = 0; i < length; i++)
            printf ("%s\n", other_email[i]);
     } else if (strcmp(item, "new.tags") == 0) {
+
        const char **tags;
        size_t i, length;

        tags = notmuch_config_get_new_tags (config, &length);
        for (i = 0; i < length; i++)
            printf ("%s\n", tags[i]);
+
     } else {
        char **value;
        size_t i, length;
diff --git a/notmuch-new.c b/notmuch-new.c
index 82acf69..db52961 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -50,6 +50,9 @@ typedef struct {
     const char **new_ignore;
     size_t new_ignore_length;

+    const char **changed_tags;
+    size_t changed_tags_length;
+
     int total_files;
     int processed_files;
     int added_messages, removed_messages, renamed_messages;
@@ -274,8 +277,12 @@ add_file (notmuch_database_t *notmuch, const char 
*filename,
        break;
     /* Non-fatal issues (go on to next file). */
     case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
+       notmuch_message_freeze (message);
+       for (tag = state->changed_tags; *tag != NULL; tag++)
+           notmuch_message_add_tag (message, *tag);
        if (state->synchronize_flags)
            notmuch_message_maildir_flags_to_tags (message);
+       notmuch_message_thaw (message);
        break;
     case NOTMUCH_STATUS_FILE_NOT_EMAIL:
        fprintf (stderr, "Note: Ignoring non-mail file: %s\n", filename);
@@ -809,13 +816,25 @@ remove_filename (notmuch_database_t *notmuch,

     status = notmuch_database_remove_message (notmuch, path);
     if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {
-       add_files_state->renamed_messages++;
-       if (add_files_state->synchronize_flags == TRUE)
-           notmuch_message_maildir_flags_to_tags (message);
-       status = NOTMUCH_STATUS_SUCCESS;
+
+    add_files_state->renamed_messages++;
+
+    /* add changed tags */
+    const char **tag;
+    for (tag = add_files_state->changed_tags; *tag != NULL; tag++)
+        notmuch_message_add_tag (message, *tag);
+
+    if (add_files_state->synchronize_flags == TRUE)
+        notmuch_message_maildir_flags_to_tags (message);
+
+    status = NOTMUCH_STATUS_SUCCESS;
+
     } else if (status == NOTMUCH_STATUS_SUCCESS) {
-       add_files_state->removed_messages++;
+
+      add_files_state->removed_messages++;
+
     }
+
     notmuch_message_destroy (message);

   DONE:
@@ -946,8 +965,13 @@ notmuch_new_command (notmuch_config_t *config, int argc, 
char *argv[])
     else if (verbose)
        add_files_state.verbosity = VERBOSITY_VERBOSE;

+    /* tags for added files */
     add_files_state.new_tags = notmuch_config_get_new_tags (config, 
&add_files_state.new_tags_length);
     add_files_state.new_ignore = notmuch_config_get_new_ignore (config, 
&add_files_state.new_ignore_length);
+
+    /* tags for changed files */
+    add_files_state.changed_tags = notmuch_config_get_changed_tags (config, 
&add_files_state.changed_tags_length);
+
     add_files_state.synchronize_flags = 
notmuch_config_get_maildir_synchronize_flags (config);
     db_path = notmuch_config_get_database_path (config);

diff --git a/notmuch-setup.c b/notmuch-setup.c
index 36a6171..cf99ee0 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -131,6 +131,8 @@ notmuch_setup_command (notmuch_config_t *config,
     unsigned int i;
     const char **new_tags;
     size_t new_tags_len;
+    const char **changed_tags;
+    size_t changed_tags_len;
     const char **search_exclude_tags;
     size_t search_exclude_tags_len;

@@ -206,6 +208,21 @@ notmuch_setup_command (notmuch_config_t *config,
        g_ptr_array_free (tags, TRUE);
     }

+    changed_tags = notmuch_config_get_changed_tags (config, &changed_tags_len);
+
+    printf ("Tags to apply to all changed messages (separated by spaces) [");
+    print_tag_list (changed_tags, changed_tags_len);
+    prompt ("]: ");
+
+    if (strlen (response)) {
+       GPtrArray *tags = parse_tag_list (config, response);
+
+       notmuch_config_set_changed_tags (config, (const char **) tags->pdata,
+                                    tags->len);
+
+       g_ptr_array_free (tags, TRUE);
+    }
+

     search_exclude_tags = notmuch_config_get_search_exclude_tags (config, 
&search_exclude_tags_len);

diff --git a/test/T030-config.sh b/test/T030-config.sh
index ca4cf33..d1e095b 100755
--- a/test/T030-config.sh
+++ b/test/T030-config.sh
@@ -52,6 +52,7 @@ user.primary_email=test_suite at notmuchmail.org
 user.other_email=test_suite_other at notmuchmail.org;test_suite at 
otherdomain.org
 new.tags=unread;inbox;
 new.ignore=
+new.changed_tags=
 search.exclude_tags=
 maildir.synchronize_flags=true
 foo.string=this is another string value
diff --git a/test/T040-setup.sh b/test/T040-setup.sh
index 124ef1c..7e37ea1 100755
--- a/test/T040-setup.sh
+++ b/test/T040-setup.sh
@@ -11,6 +11,7 @@ another.suite at example.com

 /path/to/maildir
 foo bar
+chaz
 baz
 EOF
 output=$(notmuch --config=new-notmuch-config config list)
@@ -21,6 +22,7 @@ user.primary_email=test.suite at example.com
 user.other_email=another.suite at example.com;
 new.tags=foo;bar;
 new.ignore=
+new.changed_tags=chaz;
 search.exclude_tags=baz;
 maildir.synchronize_flags=true"

-- 
1.9.1

Reply via email to