unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 1/4] cli: make caller check tag count in parse_tag_command_line
@ 2013-01-22 17:41 Jani Nikula
  2013-01-22 17:41 ` [PATCH 2/4] cli: add --remove-all option to "notmuch tag" Jani Nikula
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Jani Nikula @ 2013-01-22 17:41 UTC (permalink / raw)
  To: notmuch

---
 notmuch-tag.c |    5 +++++
 tag-util.c    |    5 -----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/notmuch-tag.c b/notmuch-tag.c
index d9daf8f..b2b22f7 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -234,6 +234,11 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
 	if (parse_tag_command_line (ctx, argc - opt_index, argv + opt_index,
 				    &query_string, tag_ops))
 	    return 1;
+
+	if (tag_op_list_size (tag_ops) == 0) {
+	    fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n");
+	    return 1;
+	}
     }
 
     config = notmuch_config_open (ctx, NULL, NULL);
diff --git a/tag-util.c b/tag-util.c
index 701d329..c5f5859 100644
--- a/tag-util.c
+++ b/tag-util.c
@@ -188,11 +188,6 @@ parse_tag_command_line (void *ctx, int argc, char **argv,
 	tag_op_list_append (tag_ops, argv[i] + 1, is_remove);
     }
 
-    if (tag_op_list_size (tag_ops) == 0) {
-	fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n");
-	return TAG_PARSE_INVALID;
-    }
-
     *query_str = query_string_from_args (ctx, argc - i, &argv[i]);
 
     if (*query_str == NULL || **query_str == '\0') {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] cli: add --remove-all option to "notmuch tag"
  2013-01-22 17:41 [PATCH 1/4] cli: make caller check tag count in parse_tag_command_line Jani Nikula
@ 2013-01-22 17:41 ` Jani Nikula
  2013-02-25 19:34   ` Jani Nikula
  2013-01-22 17:41 ` [PATCH 3/4] man: document notmuch tag --remove-all Jani Nikula
  2013-01-22 17:41 ` [PATCH 4/4] test: " Jani Nikula
  2 siblings, 1 reply; 6+ messages in thread
From: Jani Nikula @ 2013-01-22 17:41 UTC (permalink / raw)
  To: notmuch

Add --remove-all option to "notmuch tag" to remove all tags from the
messages matching query before applying the tag changes. This allows
removal of all tags and unconditional setting of the tags of a
message:

$ notmuch tag --remove-all id:foo@example.com
$ notmuch tag --remove-all +foo +bar id:foo@example.com

without having to resort to the complicated (and still quoting
broken):

$ notmuch tag $(notmuch search --output=tags '*' | sed 's/^/-/') \
  id:foo@example.com
$ notmuch tag $(notmuch search --output=tags '*' | sed 's/^/-/') \
  +foo +bar id:foo@example.com
---
 notmuch-tag.c |   28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/notmuch-tag.c b/notmuch-tag.c
index b2b22f7..e674215 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -99,12 +99,15 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
     notmuch_message_t *message;
     int ret = NOTMUCH_STATUS_SUCCESS;
 
-    /* Optimize the query so it excludes messages that already have
-     * the specified set of tags. */
-    query_string = _optimize_tag_query (ctx, query_string, tag_ops);
-    if (query_string == NULL) {
-	fprintf (stderr, "Out of memory.\n");
-	return 1;
+    if (! (flags & TAG_FLAG_REMOVE_ALL)) {
+	/* Optimize the query so it excludes messages that already
+	 * have the specified set of tags. */
+	query_string = _optimize_tag_query (ctx, query_string, tag_ops);
+	if (query_string == NULL) {
+	    fprintf (stderr, "Out of memory.\n");
+	    return 1;
+	}
+	flags |= TAG_FLAG_PRE_OPTIMIZED;
     }
 
     query = notmuch_query_create (notmuch, query_string);
@@ -120,7 +123,7 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
 	 notmuch_messages_valid (messages) && ! interrupted;
 	 notmuch_messages_move_to_next (messages)) {
 	message = notmuch_messages_get (messages);
-	ret = tag_op_list_apply (message, tag_ops, flags | TAG_FLAG_PRE_OPTIMIZED);
+	ret = tag_op_list_apply (message, tag_ops, flags);
 	notmuch_message_destroy (message);
 	if (ret != NOTMUCH_STATUS_SUCCESS)
 	    break;
@@ -187,6 +190,7 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
     struct sigaction action;
     tag_op_flag_t tag_flags = TAG_FLAG_NONE;
     notmuch_bool_t batch = FALSE;
+    notmuch_bool_t remove_all = FALSE;
     FILE *input = stdin;
     char *input_file_name = NULL;
     int opt_index;
@@ -202,6 +206,7 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
     notmuch_opt_desc_t options[] = {
 	{ NOTMUCH_OPT_BOOLEAN, &batch, "batch", 0, 0 },
 	{ NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },
+	{ NOTMUCH_OPT_BOOLEAN, &remove_all, "remove-all", 0, 0 },
 	{ 0, 0, 0, 0, 0 }
     };
 
@@ -224,6 +229,10 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
 	    fprintf (stderr, "Can't specify both cmdline and stdin!\n");
 	    return 1;
 	}
+	if (remove_all) {
+	    fprintf (stderr, "Can't specify both --remove-all and --batch\n");
+	    return 1;
+	}
     } else {
 	tag_ops = tag_op_list_create (ctx);
 	if (tag_ops == NULL) {
@@ -235,7 +244,7 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
 				    &query_string, tag_ops))
 	    return 1;
 
-	if (tag_op_list_size (tag_ops) == 0) {
+	if (tag_op_list_size (tag_ops) == 0 && ! remove_all) {
 	    fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n");
 	    return 1;
 	}
@@ -252,6 +261,9 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
     if (notmuch_config_get_maildir_synchronize_flags (config))
 	tag_flags |= TAG_FLAG_MAILDIR_SYNC;
 
+    if (remove_all)
+	tag_flags |= TAG_FLAG_REMOVE_ALL;
+
     if (batch)
 	ret = tag_file (ctx, notmuch, tag_flags, input);
     else
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] man: document notmuch tag --remove-all
  2013-01-22 17:41 [PATCH 1/4] cli: make caller check tag count in parse_tag_command_line Jani Nikula
  2013-01-22 17:41 ` [PATCH 2/4] cli: add --remove-all option to "notmuch tag" Jani Nikula
@ 2013-01-22 17:41 ` Jani Nikula
  2013-01-22 17:41 ` [PATCH 4/4] test: " Jani Nikula
  2 siblings, 0 replies; 6+ messages in thread
From: Jani Nikula @ 2013-01-22 17:41 UTC (permalink / raw)
  To: notmuch

---
 man/man1/notmuch-tag.1 |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/man/man1/notmuch-tag.1 b/man/man1/notmuch-tag.1
index 081bd0e..493b256 100644
--- a/man/man1/notmuch-tag.1
+++ b/man/man1/notmuch-tag.1
@@ -4,7 +4,7 @@ notmuch-tag \- add/remove tags for all messages matching the search terms
 
 .SH SYNOPSIS
 .B notmuch tag
-.RI "+<" tag ">|\-<" tag "> [...] [\-\-] <" search-term "> [...]"
+.RI [ options "...] +<" tag ">|\-<" tag "> [...] [\-\-] <" search-term "> [...]"
 
 .B notmuch tag
 .RI "--batch"
@@ -40,6 +40,16 @@ Supported options for
 include
 .RS 4
 .TP 4
+.BR \-\-remove\-all
+
+Remove all tags from each message matching the search terms before
+applying the tag changes appearing on the command line. This means
+setting the tags of each message to the tags to be added. If there are
+no tags to be added, the messages will have no tags.
+.RE
+
+.RS 4
+.TP 4
 .BR \-\-batch
 
 Read batch tagging operations from a file (stdin by default). This is more
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] test: notmuch tag --remove-all
  2013-01-22 17:41 [PATCH 1/4] cli: make caller check tag count in parse_tag_command_line Jani Nikula
  2013-01-22 17:41 ` [PATCH 2/4] cli: add --remove-all option to "notmuch tag" Jani Nikula
  2013-01-22 17:41 ` [PATCH 3/4] man: document notmuch tag --remove-all Jani Nikula
@ 2013-01-22 17:41 ` Jani Nikula
  2 siblings, 0 replies; 6+ messages in thread
From: Jani Nikula @ 2013-01-22 17:41 UTC (permalink / raw)
  To: notmuch

---
 test/tagging |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/test/tagging b/test/tagging
index 1f5632c..dc118f3 100755
--- a/test/tagging
+++ b/test/tagging
@@ -30,6 +30,22 @@ test_expect_equal "$output" "\
 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread)
 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)"
 
+test_begin_subtest "Remove all"
+notmuch tag --remove-all One
+notmuch tag --remove-all +tag5 +tag6 +unread Two
+output=$(notmuch search \* | notmuch_search_sanitize)
+test_expect_equal "$output" "\
+thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; One ()
+thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Two (tag5 tag6 unread)"
+
+test_begin_subtest "Remove all with a no-op"
+notmuch tag +inbox +tag1 +unread One
+notmuch tag --remove-all +foo +inbox +tag1 -foo +unread Two
+output=$(notmuch search \* | notmuch_search_sanitize)
+test_expect_equal "$output" "\
+thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread)
+thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)"
+
 test_begin_subtest "Special characters in tags"
 notmuch tag +':" ' \*
 notmuch tag -':" ' Two
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/4] cli: add --remove-all option to "notmuch tag"
  2013-01-22 17:41 ` [PATCH 2/4] cli: add --remove-all option to "notmuch tag" Jani Nikula
@ 2013-02-25 19:34   ` Jani Nikula
  2013-02-25 21:53     ` David Bremner
  0 siblings, 1 reply; 6+ messages in thread
From: Jani Nikula @ 2013-02-25 19:34 UTC (permalink / raw)
  To: notmuch

On Tue, 22 Jan 2013, Jani Nikula <jani@nikula.org> wrote:
> Add --remove-all option to "notmuch tag" to remove all tags from the
> messages matching query before applying the tag changes. This allows
> removal of all tags and unconditional setting of the tags of a
> message:
>
> $ notmuch tag --remove-all id:foo@example.com
> $ notmuch tag --remove-all +foo +bar id:foo@example.com
>
> without having to resort to the complicated (and still quoting
> broken):
>
> $ notmuch tag $(notmuch search --output=tags '*' | sed 's/^/-/') \
>   id:foo@example.com
> $ notmuch tag $(notmuch search --output=tags '*' | sed 's/^/-/') \
>   +foo +bar id:foo@example.com

Just today there was another question on IRC about removing all tags,
and the reply from amdragon was along the lines of the above. This
series would make things so much easier... reviews, anyone? ;)

BR,
Jani.


> ---
>  notmuch-tag.c |   28 ++++++++++++++++++++--------
>  1 file changed, 20 insertions(+), 8 deletions(-)
>
> diff --git a/notmuch-tag.c b/notmuch-tag.c
> index b2b22f7..e674215 100644
> --- a/notmuch-tag.c
> +++ b/notmuch-tag.c
> @@ -99,12 +99,15 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
>      notmuch_message_t *message;
>      int ret = NOTMUCH_STATUS_SUCCESS;
>  
> -    /* Optimize the query so it excludes messages that already have
> -     * the specified set of tags. */
> -    query_string = _optimize_tag_query (ctx, query_string, tag_ops);
> -    if (query_string == NULL) {
> -	fprintf (stderr, "Out of memory.\n");
> -	return 1;
> +    if (! (flags & TAG_FLAG_REMOVE_ALL)) {
> +	/* Optimize the query so it excludes messages that already
> +	 * have the specified set of tags. */
> +	query_string = _optimize_tag_query (ctx, query_string, tag_ops);
> +	if (query_string == NULL) {
> +	    fprintf (stderr, "Out of memory.\n");
> +	    return 1;
> +	}
> +	flags |= TAG_FLAG_PRE_OPTIMIZED;
>      }
>  
>      query = notmuch_query_create (notmuch, query_string);
> @@ -120,7 +123,7 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
>  	 notmuch_messages_valid (messages) && ! interrupted;
>  	 notmuch_messages_move_to_next (messages)) {
>  	message = notmuch_messages_get (messages);
> -	ret = tag_op_list_apply (message, tag_ops, flags | TAG_FLAG_PRE_OPTIMIZED);
> +	ret = tag_op_list_apply (message, tag_ops, flags);
>  	notmuch_message_destroy (message);
>  	if (ret != NOTMUCH_STATUS_SUCCESS)
>  	    break;
> @@ -187,6 +190,7 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
>      struct sigaction action;
>      tag_op_flag_t tag_flags = TAG_FLAG_NONE;
>      notmuch_bool_t batch = FALSE;
> +    notmuch_bool_t remove_all = FALSE;
>      FILE *input = stdin;
>      char *input_file_name = NULL;
>      int opt_index;
> @@ -202,6 +206,7 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
>      notmuch_opt_desc_t options[] = {
>  	{ NOTMUCH_OPT_BOOLEAN, &batch, "batch", 0, 0 },
>  	{ NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },
> +	{ NOTMUCH_OPT_BOOLEAN, &remove_all, "remove-all", 0, 0 },
>  	{ 0, 0, 0, 0, 0 }
>      };
>  
> @@ -224,6 +229,10 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
>  	    fprintf (stderr, "Can't specify both cmdline and stdin!\n");
>  	    return 1;
>  	}
> +	if (remove_all) {
> +	    fprintf (stderr, "Can't specify both --remove-all and --batch\n");
> +	    return 1;
> +	}
>      } else {
>  	tag_ops = tag_op_list_create (ctx);
>  	if (tag_ops == NULL) {
> @@ -235,7 +244,7 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
>  				    &query_string, tag_ops))
>  	    return 1;
>  
> -	if (tag_op_list_size (tag_ops) == 0) {
> +	if (tag_op_list_size (tag_ops) == 0 && ! remove_all) {
>  	    fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n");
>  	    return 1;
>  	}
> @@ -252,6 +261,9 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
>      if (notmuch_config_get_maildir_synchronize_flags (config))
>  	tag_flags |= TAG_FLAG_MAILDIR_SYNC;
>  
> +    if (remove_all)
> +	tag_flags |= TAG_FLAG_REMOVE_ALL;
> +
>      if (batch)
>  	ret = tag_file (ctx, notmuch, tag_flags, input);
>      else
> -- 
> 1.7.10.4

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/4] cli: add --remove-all option to "notmuch tag"
  2013-02-25 19:34   ` Jani Nikula
@ 2013-02-25 21:53     ` David Bremner
  0 siblings, 0 replies; 6+ messages in thread
From: David Bremner @ 2013-02-25 21:53 UTC (permalink / raw)
  To: Jani Nikula, notmuch

Jani Nikula <jani@nikula.org> writes:

>>
>> $ notmuch tag $(notmuch search --output=tags '*' | sed 's/^/-/') \
>>   id:foo@example.com
>> $ notmuch tag $(notmuch search --output=tags '*' | sed 's/^/-/') \
>>   +foo +bar id:foo@example.com

In the special case that the query really is a message-id, the following
should work

echo "-- id:foo@example" | notmuch restore --format=batch-tag

should work.

Weirdly, that seems to even remove that attachment tag, I'm not sure if
that is a bug.

Anyway your patches are more general.

Sorry, that's not a review yet.

d

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-02-25 21:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-22 17:41 [PATCH 1/4] cli: make caller check tag count in parse_tag_command_line Jani Nikula
2013-01-22 17:41 ` [PATCH 2/4] cli: add --remove-all option to "notmuch tag" Jani Nikula
2013-02-25 19:34   ` Jani Nikula
2013-02-25 21:53     ` David Bremner
2013-01-22 17:41 ` [PATCH 3/4] man: document notmuch tag --remove-all Jani Nikula
2013-01-22 17:41 ` [PATCH 4/4] test: " Jani Nikula

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).