[notmuch] Using notmuch as an address book for tab-completion

2010-03-20 Thread Jesse Rosenthal
Normally, I wouldn't respond to myself to fix a typo, but this seemed
important.

> Remember, neither of these will do you much good with the shared lib and
> cnotmuch installed.

I meant, of course, that neither would do you much good *WITHOUT* the
shared lib and cnotmuch installed.

Apologies,
Jesse


[notmuch] Using notmuch as an address book for tab-completion

2010-03-20 Thread Jesse Rosenthal
Dear All,

There was some talk on IRC ages ago about using notmuch as an
address-book for tab-completion in emacs message mode. Thanks to some
great recent work (Ingmar Vanhassel's shared lib and Sebastians's
cnotmuch python lib) I have been able to take a first step in that
direction. I've written a python script (with some help and suggestions
from spaetz) which can perform the address-book functionality, and a
backend for emacs's EUDC address-lookup functionality to access the
script.

They are available by the following commands:

git clone http://jkr.acm.jhu.edu/git/notmuch_addresses.git
git clone http://jkr.acm.jhu.edu/git/notmuch_eudc.git

Remember, neither of these will do you much good with the shared lib and
cnotmuch installed.

At the moment, the script works by search addresses that you have
written to (or CC'd or BCC'd) in the past. This seems like a good
utility-speed tradeoff, but it would be easy to hack the script to
search a different set of messages. Give three letters (it looks through
first names, last names, and email addresses) it returns results from my
12K messages in well under a second. 

The responses are sorted by frequency, and each email address is
associated with the most frequently used real name (null real-names are
avoided, unless they're the only option).

The script can be run from the command line by:
$ python notmuch_addresses.py query

To get tab completion from emacs, you have to install the script into
your path, make it executable, and then put my eudcb-notmuch.el file
into your load path (you should byte-compile it too). DON'T CHANGE THE
TITLE OF THE .EL FILE! EUDC looks for a specific title based on
protocol.

Then add the following to your .emacs:

(eudc-set-server "localhost" 'notmuch t)
(setq eudc-server-hotlist '(("localhost" . notmuch)))
(setq eudc-inline-expansion-servers 'hotlist)

if you wish to use BBDB too (likely before you use notmuch), then
you should use something like this:

(eudc-set-server "localhost" 'bbdb t)
(eudc-protocol-set 'eudc-inline-expansion-format 
   '("%s %s <%s>" firstname lastname net)
   'bbdb)
(eudc-set-server "localhost" 'notmuch t)
(setq eudc-server-hotlist '(("localhost" . bbdb)
("localhost" . notmuch)))
(setq eudc-inline-expansion-servers 'hotlist)

That should do it. Please let me know if it works for you.

(For those of you who care, eudcb-notmuch.el has a few hacky bits to
hide the fact that notmuch really isn't an address book. That is, it
doesn't know the difference between names and email addresses. So
everything you enter just goes in as one string, which I call "name."
Back-end stuff, but if you're looking through the code, that might make
a few things clearer.)

Best,
Jesse


[notmuch] Tag search peculiarities

2010-03-20 Thread Ben Gamari
On Thu, 18 Mar 2010 15:27:12 +0100, Sandra Snan  
wrote:
> Hey, Ben.
> Ben Gamari  wrote:
> > notmuch tag -new tag:new and tag:list notmuch tag -new +inbox tag:new
> 
> Is there a new line between the calls? Like:
> notmuch tag -new tag:new and tag:list # removes new from list
> notmuch tag -new +inbox tag:new # replaces those that still are new with inbox
> 
Eh? They are two separate notmuch invocations.

> > However, I found that mailing list traffic was still getting through.
> 
> What do you mean by ???through Do you mean that there still are
> messages tagged both inbox and list? Even though you can???t search for
> them?
> 
Yeah, poor choice of words. After the two commands above ran, my mailing list
messages were tagged with new, inbox.

> If a message is tagged both inbox and list, but not new then the two
> lines of your script that you posted so far wouldn???t change it, and it
> would still bo both inbox and list.
> 
> It???s risky being so dependent on the new tag.
> 
Eh? I fail to see why. It's no more risky than depending on the inbox tag.

> > After investigating further, I found that any query in the form of 
> > "tag:inbox
> > and tag:$TAG" would return no results. Strangely, all other combinations of 
> > tag
> > searches (i.e. "tag:lkml and tag:unread") seem to work just fine.
> > 
> > Has anyone else noticed this sort of behavior? Does the inbox tag have some
> > special signifigance that I should know of?
> 
> Yes, many versions of the reading client (for example, the version of
> notmuch.el that ships with the notmuch package in debian) remove the
> inbox tag from messages once you scroll past them or when you press
> the key that???s bound to notmuch-show-archive-thread (default is ???a???).
> 
I guess I should have been more explicit. I meant in notmuch itself, not the
clients.

> > Is my index just FUBAR? (the ladder would be very strange
> > considering it's only a few days old and I can't think of any
> > crashes, etc. that might have corrupted it) Any ideas for debugging?
> 
> Add the tags manually to a few messages, search for them again, and be
> sure to not run your tagging script while looking at this problem.
> 
> Michal???s tip, looking at a few lines of notmuch dump, is a good idea
> too. Notmuch dump is fast, so don???t be afraid (notmuch restore on the
> other hand??? but even that completes fast enough.)
> 
> I???ve often been surprised at weird tag situations then realized that
> it was old versions of my own scripts that had ran in the background
> and I???ve forgotten about it.
> 
Indeed. Hopefully it will be something so simple. I'm currently blissfully
unaware of the internals of Xapian, and would really like to remain that way.

Thanks,

- Ben


[notmuch] [PATCH 5/5] Added backwards iterator to tags

2010-03-20 Thread Ruben Pollan
Added the functions notmuch_tags_move_to_prevoius,
notmuch_tags_move_to_last and  notmuch_tags_move_to_first to notmuch
library. With them is possible to iterate backwards on tags.

* notmuch_tags_move_to_prevoius do the opposite than
  notmuch_tags_move_to_next, getting the tags iterator one
  position backwards.

* notmuch_tags_move_to_last move the iterator to the first last tag.

* notmuch_tags_move_to_first move the iterator to the first valid tag.
---
 lib/notmuch.h |   28 
 lib/tags.c|   21 +
 2 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index b96b624..dc668dc 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -1022,6 +1022,15 @@ notmuch_tags_valid (notmuch_tags_t *tags);
 const char *
 notmuch_tags_get (notmuch_tags_t *tags);

+/* Move the 'tags' iterator to the first tag.
+ *
+ * After that the 'tags' iterator will be set to the first valid 
+ * tag, so it can be use to iterate with 
+ * notmuch_tags_move_to_next.
+ */
+void
+notmuch_tags_move_to_first (notmuch_tags_t *tags);
+
 /* Move the 'tags' iterator to the next tag.
  *
  * If 'tags' is already pointing at the last tag then the iterator
@@ -1035,6 +1044,25 @@ notmuch_tags_get (notmuch_tags_t *tags);
 void
 notmuch_tags_move_to_next (notmuch_tags_t *tags);

+/* Move the 'tags' iterator to the last tag.
+ *
+ * After that the 'tags' iterator will be set to the last valid 
+ * tag, so it can be use to iterate with 
+ * notmuch_tags_move_to_previous.
+ */
+void
+notmuch_tags_move_to_last (notmuch_tags_t *tags);
+
+/* Move the 'tags' iterator to the previous tag.
+ *
+ * If 'tags' is already pointing at the first tag then the
+ * iterator will be moved to a point just beyond that first tag,
+ * (where notmuch_tags_valid will return FALSE and
+ * notmuch_tags_get will return NULL).
+ */
+void
+notmuch_tags_move_to_previous (notmuch_tags_t *tags);
+
 /* Destroy a notmuch_tags_t object.
  *
  * It's not strictly necessary to call this function. All memory from
diff --git a/lib/tags.c b/lib/tags.c
index 8fe4a3f..9c9a897 100644
--- a/lib/tags.c
+++ b/lib/tags.c
@@ -105,6 +105,12 @@ notmuch_tags_get (notmuch_tags_t *tags)
 }

 void
+notmuch_tags_move_to_first (notmuch_tags_t *tags)
+{
+tags->iterator = g_list_first (tags->tags);
+}
+
+void
 notmuch_tags_move_to_next (notmuch_tags_t *tags)
 {
 if (tags->iterator == NULL)
@@ -114,6 +120,21 @@ notmuch_tags_move_to_next (notmuch_tags_t *tags)
 }

 void
+notmuch_tags_move_to_last (notmuch_tags_t *tags)
+{
+tags->iterator = g_list_last (tags->tags);
+}
+
+void
+notmuch_tags_move_to_previous (notmuch_tags_t *tags)
+{
+if (tags->iterator == NULL)
+   return;
+
+tags->iterator = tags->iterator->prev;
+}
+
+void
 notmuch_tags_destroy (notmuch_tags_t *tags)
 {
 talloc_free (tags);
-- 
1.7.0



[notmuch] [PATCH 4/5] Added backwards iterator to threads

2010-03-20 Thread Ruben Pollan
Added the functions notmuch_threads_move_to_prevoius,
notmuch_threads_move_to_last and  notmuch_threads_move_to_first to
notmuch library. With them is possible to iterate backwards on threads.

* notmuch_threads_move_to_prevoius do the opposite than
  notmuch_threads_move_to_next, getting the threads iterator one
  position backwards.

* notmuch_threads_move_to_last move the iterator to the first last thread.

* notmuch_threads_move_to_first move the iterator to the first valid
  thread.

For it has been implemented notmuch_thread_list_t structur that stores
the thread_ids so the backwards iteration gets the thread_id in the same
order that was show on forward iteration.
---
 lib/notmuch.h |   28 +++
 lib/query.cc  |  143 -
 2 files changed, 159 insertions(+), 12 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index 753f3bb..b96b624 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -466,6 +466,15 @@ notmuch_threads_valid (notmuch_threads_t *threads);
 notmuch_thread_t *
 notmuch_threads_get (notmuch_threads_t *threads);

+/* Move the 'threads' iterator to the first thread.
+ *
+ * After that the 'threads' iterator will be set to the first valid 
+ * thread, so it can be use to iterate with 
+ * notmuch_threads_move_to_next.
+ */
+void
+notmuch_threads_move_to_first (notmuch_threads_t *threads);
+
 /* Move the 'threads' iterator to the next thread.
  *
  * If 'threads' is already pointing at the last thread then the
@@ -479,6 +488,25 @@ notmuch_threads_get (notmuch_threads_t *threads);
 void
 notmuch_threads_move_to_next (notmuch_threads_t *threads);

+/* Move the 'threads' iterator to the last thread.
+ *
+ * After that the 'threads' iterator will be set to the last valid 
+ * thread, so it can be use to iterate with 
+ * notmuch_threads_move_to_previous.
+ */
+void
+notmuch_threads_move_to_last (notmuch_threads_t *threads);
+
+/* Move the 'threads' iterator to the previous thread.
+ *
+ * If 'threads' is already pointing at the first thread then the
+ * iterator will be moved to a point just beyond that first thread,
+ * (where notmuch_threads_valid will return FALSE and
+ * notmuch_threads_get will return NULL).
+ */
+void
+notmuch_threads_move_to_previous (notmuch_threads_t *threads);
+
 /* Destroy a notmuch_threads_t object.
  *
  * It's not strictly necessary to call this function. All memory from
diff --git a/lib/query.cc b/lib/query.cc
index 44950c1..39985e7 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -39,13 +39,25 @@ typedef struct _notmuch_mset_messages {
 Xapian::MSetIterator iterator_end;
 } notmuch_mset_messages_t;

+typedef struct _notmuch_thread_node {
+const char *thread_id;
+struct _notmuch_thread_node *next;
+struct _notmuch_thread_node *prev;
+} notmuch_thread_node_t;
+
+typedef struct _notmuch_thread_list {
+notmuch_thread_node_t *head;
+notmuch_thread_node_t *tail;
+notmuch_thread_node_t *iterator;
+} notmuch_thread_list_t;
+
 struct _notmuch_threads {
 notmuch_query_t *query;
 GHashTable *threads;
 notmuch_messages_t *messages;

-/* This thread ID is our iterator state. */
-const char *thread_id;
+/* thread list with the thread_id of the showed messages */
+notmuch_thread_list_t *list;
 };

 notmuch_query_t *
@@ -269,6 +281,64 @@ _notmuch_mset_messages_move_to_previous 
(notmuch_messages_t *messages)
 }
 }

+static void
+_notmuch_thread_list_create (notmuch_thread_list_t *list, const char 
*thread_id)
+{
+list->head = talloc (list, notmuch_thread_node_t);
+list->tail = list->head;
+list->iterator = list->head;
+list->iterator->thread_id = thread_id;
+list->iterator->next = NULL;
+list->iterator->prev = NULL;
+}
+
+static void
+_notmuch_thread_list_append (notmuch_thread_list_t *list, const char 
*thread_id)
+{
+list->tail->next = talloc (list, notmuch_thread_node_t);
+list->iterator = list->tail->next;
+list->iterator->thread_id = thread_id;
+list->iterator->next = NULL;
+list->iterator->prev = list->tail;
+list->tail = list->iterator;
+}
+
+static const char *
+_notmuch_thread_list_get_id (notmuch_thread_list_t *list)
+{
+return list->iterator->thread_id;
+}
+
+static notmuch_bool_t
+_notmuch_thread_list_valid (notmuch_thread_list_t *list)
+{
+return (list->iterator != NULL);
+}
+
+static void
+_notmuch_thread_list_move_to_first (notmuch_thread_list_t *list)
+{
+list->iterator = list->head;
+}
+
+static void
+_notmuch_thread_list_move_to_next (notmuch_thread_list_t *list)
+{
+list->iterator = list->iterator->next;
+}
+
+static void
+_notmuch_thread_list_move_to_last (notmuch_thread_list_t *list)
+{
+list->iterator = list->tail;
+}
+
+static void
+_notmuch_thread_list_move_to_previous (notmuch_thread_list_t *list)
+{
+list->iterator = list->iterator->prev;
+}
+
 /* Glib objects force use to use a talloc destructor as well, (but not
  * nearly as ugly as the for messages due to 

[notmuch] [PATCH 3/5] Move the logic of threads iterator out of 'valid'

2010-03-20 Thread Ruben Pollan
The logic of notmuch_threads_move_to_next iterator was on
notmuch_threads_valid function. Now notmuch_threads_valid just check if
the iterator is valid and is notmuch_threads_move_to_next wich actually
update the iterator.
---
 lib/query.cc |   47 ---
 1 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index 970c35a..44950c1 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -285,6 +285,7 @@ notmuch_threads_t *
 notmuch_query_search_threads (notmuch_query_t *query)
 {
 notmuch_threads_t *threads;
+notmuch_message_t *message;

 threads = talloc (query, notmuch_threads_t);
 if (threads == NULL)
@@ -296,7 +297,10 @@ notmuch_query_search_threads (notmuch_query_t *query)

 threads->messages = notmuch_query_search_messages (query);

-threads->thread_id = NULL;
+message = notmuch_messages_get (threads->messages);
+threads->thread_id = notmuch_message_get_thread_id (message);
+g_hash_table_insert (threads->threads,
+ xstrdup (threads->thread_id), NULL);

 talloc_set_destructor (threads, _notmuch_threads_destructor);

@@ -312,10 +316,25 @@ notmuch_query_destroy (notmuch_query_t *query)
 notmuch_bool_t
 notmuch_threads_valid (notmuch_threads_t *threads)
 {
-notmuch_message_t *message;
+return (threads->thread_id != NULL);
+}

-if (threads->thread_id)
-   return TRUE;
+notmuch_thread_t *
+notmuch_threads_get (notmuch_threads_t *threads)
+{
+if (! notmuch_threads_valid (threads))
+   return NULL;
+
+return _notmuch_thread_create (threads->query,
+  threads->query->notmuch,
+  threads->thread_id,
+  threads->query->query_string);
+}
+
+void
+notmuch_threads_move_to_next (notmuch_threads_t *threads)
+{
+notmuch_message_t *message;

 while (notmuch_messages_valid (threads->messages))
 {
@@ -330,33 +349,15 @@ notmuch_threads_valid (notmuch_threads_t *threads)
g_hash_table_insert (threads->threads,
 xstrdup (threads->thread_id), NULL);
notmuch_messages_move_to_next (threads->messages);
-   return TRUE;
+   return;
}

notmuch_messages_move_to_next (threads->messages);
 }

 threads->thread_id = NULL;
-return FALSE;
-}
-
-notmuch_thread_t *
-notmuch_threads_get (notmuch_threads_t *threads)
-{
-if (! notmuch_threads_valid (threads))
-   return NULL;
-
-return _notmuch_thread_create (threads->query,
-  threads->query->notmuch,
-  threads->thread_id,
-  threads->query->query_string);
 }

-void
-notmuch_threads_move_to_next (notmuch_threads_t *threads)
-{
-threads->thread_id = NULL;
-}

 void
 notmuch_threads_destroy (notmuch_threads_t *threads)
-- 
1.7.0



[notmuch] [PATCH 2/5] Added backwards iterator to messages

2010-03-20 Thread Ruben Pollan
Added the functions notmuch_messages_move_to_prevoius,
notmuch_messages_move_to_last and  notmuch_messages_move_to_first to
notmuch library. With them is possible to iterate backwards on messages.

* notmuch_messages_move_to_prevoius do the opposite than
  notmuch_messages_move_to_next, getting the messages iterator one
  position backwards.

* notmuch_messages_move_to_last move the iterator to the first last
  message.

* notmuch_messages_move_to_first move the iterator to the first valid
  message.
---
 lib/messages.c|   31 +
 lib/notmuch-private.h |   10 +
 lib/notmuch.h |   28 ++
 lib/query.cc  |   52 +
 4 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/lib/messages.c b/lib/messages.c
index 2a85774..975e4b1 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -90,6 +90,7 @@ _notmuch_messages_create (notmuch_message_list_t *list)

 messages->is_of_list_type = TRUE;
 messages->iterator = list->head;
+messages->list = list;

 return messages;
 }
@@ -134,6 +135,15 @@ notmuch_messages_get (notmuch_messages_t *messages)
 }

 void
+notmuch_messages_move_to_first (notmuch_messages_t *messages)
+{
+if (! messages->is_of_list_type)
+   return _notmuch_mset_messages_move_to_first (messages);
+
+messages->iterator = messages->list->head;
+}
+
+void
 notmuch_messages_move_to_next (notmuch_messages_t *messages)
 {
 if (! messages->is_of_list_type)
@@ -146,6 +156,27 @@ notmuch_messages_move_to_next (notmuch_messages_t 
*messages)
 }

 void
+notmuch_messages_move_to_last (notmuch_messages_t *messages)
+{
+if (! messages->is_of_list_type)
+   return _notmuch_mset_messages_move_to_last (messages);
+
+messages->iterator = messages->list->tail;
+}
+
+void
+notmuch_messages_move_to_previous (notmuch_messages_t *messages)
+{
+if (! messages->is_of_list_type)
+   return _notmuch_mset_messages_move_to_previous (messages);
+
+if (messages->iterator == NULL)
+   return;
+
+messages->iterator = messages->iterator->prev;
+}
+
+void
 notmuch_messages_destroy (notmuch_messages_t *messages)
 {
 talloc_free (messages);
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 3b3f0eb..2269d2b 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -364,6 +364,7 @@ typedef struct _notmuch_message_list {
 struct _notmuch_messages {
 notmuch_bool_t is_of_list_type;
 notmuch_message_node_t *iterator;
+notmuch_message_list_t *list;
 };

 notmuch_message_list_t *
@@ -389,8 +390,17 @@ notmuch_message_t *
 _notmuch_mset_messages_get (notmuch_messages_t *messages);

 void
+_notmuch_mset_messages_move_to_first (notmuch_messages_t *messages);
+
+void
 _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages);

+void
+_notmuch_mset_messages_move_to_last (notmuch_messages_t *messages);
+
+void
+_notmuch_mset_messages_move_to_previous (notmuch_messages_t *messages);
+
 /* message.cc */

 void
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 0d9cb0f..753f3bb 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -645,6 +645,15 @@ notmuch_messages_valid (notmuch_messages_t *messages);
 notmuch_message_t *
 notmuch_messages_get (notmuch_messages_t *messages);

+/* Move the 'messages' iterator to the first message.
+ *
+ * After that the 'messages' iterator will be set to the first valid 
+ * message, so it can be use to iterate with 
+ * notmuch_messages_move_to_next.
+ */
+void
+notmuch_messages_move_to_first (notmuch_messages_t *messages);
+
 /* Move the 'messages' iterator to the next message.
  *
  * If 'messages' is already pointing at the last message then the
@@ -658,6 +667,25 @@ notmuch_messages_get (notmuch_messages_t *messages);
 void
 notmuch_messages_move_to_next (notmuch_messages_t *messages);

+/* Move the 'messages' iterator to the last message.
+ *
+ * After that the 'messages' iterator will be set to the last valid 
+ * message, so it can be use to iterate with 
+ * notmuch_messages_move_to_previous.
+ */
+void
+notmuch_messages_move_to_last (notmuch_messages_t *messages);
+
+/* Move the 'messages' iterator to the previous message.
+ *
+ * If 'messages' is already pointing at the first message then the
+ * iterator will be moved to a point just beyond that first message,
+ * (where notmuch_messages_valid will return FALSE and
+ * notmuch_messages_get will return NULL).
+ */
+void
+notmuch_messages_move_to_previous (notmuch_messages_t *messages);
+
 /* Destroy a notmuch_messages_t object.
  *
  * It's not strictly necessary to call this function. All memory from
diff --git a/lib/query.cc b/lib/query.cc
index 9266d35..970c35a 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -35,6 +35,7 @@ typedef struct _notmuch_mset_messages {
 notmuch_messages_t base;
 notmuch_database_t *notmuch;
 Xapian::MSetIterator iterator;
+Xapian::MSetIterator iterator_begin;
 Xapian::MSetIterator 

[notmuch] [PATCH 1/5] Convert notmuch_message_list_t in a doubly linked

2010-03-20 Thread Ruben Pollan
The messages list now have pointers to previous nodes, so it is possible
to iterate backwards.
---
 lib/messages.c|   18 +-
 lib/notmuch-private.h |3 ++-
 lib/thread.cc |4 ++--
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/lib/messages.c b/lib/messages.c
index db2b7a1..2a85774 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -37,20 +37,28 @@ _notmuch_message_list_create (const void *ctx)
return NULL;

 list->head = NULL;
-list->tail = >head;
+list->tail = NULL;

 return list;
 }

-/* Append 'node' (which can of course point to an arbitrarily long
- * list of nodes) to the end of 'list'.
+/* Append 'node' to the end of 'list'.
  */
 void
 _notmuch_message_list_append (notmuch_message_list_t *list,
  notmuch_message_node_t *node)
 {
-*(list->tail) = node;
-list->tail = >next;
+node->prev = list->tail;
+if (list->head)
+{
+list->tail->next = node;
+}
+else
+{
+list->head = node;
+list->tail = node;
+}
+list->tail = node;
 }

 /* Allocate a new node for 'message' and append it to the end of
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index d52d84d..3b3f0eb 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -349,11 +349,12 @@ notmuch_message_file_get_header (notmuch_message_file_t 
*message,
 typedef struct _notmuch_message_node {
 notmuch_message_t *message;
 struct _notmuch_message_node *next;
+struct _notmuch_message_node *prev;
 } notmuch_message_node_t;

 typedef struct _notmuch_message_list {
 notmuch_message_node_t *head;
-notmuch_message_node_t **tail;
+notmuch_message_node_t *tail;
 } notmuch_message_list_t;

 /* There's a rumor that there's an alternate struct _notmuch_messages
diff --git a/lib/thread.cc b/lib/thread.cc
index ec80f85..05d2c39 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -169,8 +169,8 @@ _resolve_thread_relationships (unused (notmuch_thread_t 
*thread))
  (void **) ))
{
*prev = node->next;
-   if (thread->message_list->tail == >next)
-   thread->message_list->tail = prev;
+   if (thread->message_list->tail == node)
+   thread->message_list->tail = node->prev;
node->next = NULL;
_notmuch_message_add_reply (parent, node);
} else {
-- 
1.7.0



[notmuch] reverse iterators

2010-03-20 Thread Ruben Pollan

Adds support to reverse iteration on messages, threads and tags. To revew and
think if makes sense to include them on notmuch or wait until they have a real
use.

The patch 3 "Move the logic of threads iterator out of 'valid'" is just a 
reorganization of the code, I think it makes sense to include it in notmuch even
if we decide that the reverse iterators are not included.


[notmuch] reverse iterators

2010-03-20 Thread Ruben Pollan

Adds support to reverse iteration on messages, threads and tags. To revew and
think if makes sense to include them on notmuch or wait until they have a real
use.

The patch 3 Move the logic of threads iterator out of 'valid' is just a 
reorganization of the code, I think it makes sense to include it in notmuch even
if we decide that the reverse iterators are not included.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[notmuch] [PATCH 1/5] Convert notmuch_message_list_t in a doubly linked

2010-03-20 Thread Ruben Pollan
The messages list now have pointers to previous nodes, so it is possible
to iterate backwards.
---
 lib/messages.c|   18 +-
 lib/notmuch-private.h |3 ++-
 lib/thread.cc |4 ++--
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/lib/messages.c b/lib/messages.c
index db2b7a1..2a85774 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -37,20 +37,28 @@ _notmuch_message_list_create (const void *ctx)
return NULL;
 
 list-head = NULL;
-list-tail = list-head;
+list-tail = NULL;
 
 return list;
 }
 
-/* Append 'node' (which can of course point to an arbitrarily long
- * list of nodes) to the end of 'list'.
+/* Append 'node' to the end of 'list'.
  */
 void
 _notmuch_message_list_append (notmuch_message_list_t *list,
  notmuch_message_node_t *node)
 {
-*(list-tail) = node;
-list-tail = node-next;
+node-prev = list-tail;
+if (list-head)
+{
+list-tail-next = node;
+}
+else
+{
+list-head = node;
+list-tail = node;
+}
+list-tail = node;
 }
 
 /* Allocate a new node for 'message' and append it to the end of
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index d52d84d..3b3f0eb 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -349,11 +349,12 @@ notmuch_message_file_get_header (notmuch_message_file_t 
*message,
 typedef struct _notmuch_message_node {
 notmuch_message_t *message;
 struct _notmuch_message_node *next;
+struct _notmuch_message_node *prev;
 } notmuch_message_node_t;
 
 typedef struct _notmuch_message_list {
 notmuch_message_node_t *head;
-notmuch_message_node_t **tail;
+notmuch_message_node_t *tail;
 } notmuch_message_list_t;
 
 /* There's a rumor that there's an alternate struct _notmuch_messages
diff --git a/lib/thread.cc b/lib/thread.cc
index ec80f85..05d2c39 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -169,8 +169,8 @@ _resolve_thread_relationships (unused (notmuch_thread_t 
*thread))
  (void **) parent))
{
*prev = node-next;
-   if (thread-message_list-tail == node-next)
-   thread-message_list-tail = prev;
+   if (thread-message_list-tail == node)
+   thread-message_list-tail = node-prev;
node-next = NULL;
_notmuch_message_add_reply (parent, node);
} else {
-- 
1.7.0

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


[notmuch] [PATCH 2/5] Added backwards iterator to messages

2010-03-20 Thread Ruben Pollan
Added the functions notmuch_messages_move_to_prevoius,
notmuch_messages_move_to_last and  notmuch_messages_move_to_first to
notmuch library. With them is possible to iterate backwards on messages.

* notmuch_messages_move_to_prevoius do the opposite than
  notmuch_messages_move_to_next, getting the messages iterator one
  position backwards.

* notmuch_messages_move_to_last move the iterator to the first last
  message.

* notmuch_messages_move_to_first move the iterator to the first valid
  message.
---
 lib/messages.c|   31 +
 lib/notmuch-private.h |   10 +
 lib/notmuch.h |   28 ++
 lib/query.cc  |   52 +
 4 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/lib/messages.c b/lib/messages.c
index 2a85774..975e4b1 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -90,6 +90,7 @@ _notmuch_messages_create (notmuch_message_list_t *list)
 
 messages-is_of_list_type = TRUE;
 messages-iterator = list-head;
+messages-list = list;
 
 return messages;
 }
@@ -134,6 +135,15 @@ notmuch_messages_get (notmuch_messages_t *messages)
 }
 
 void
+notmuch_messages_move_to_first (notmuch_messages_t *messages)
+{
+if (! messages-is_of_list_type)
+   return _notmuch_mset_messages_move_to_first (messages);
+
+messages-iterator = messages-list-head;
+}
+
+void
 notmuch_messages_move_to_next (notmuch_messages_t *messages)
 {
 if (! messages-is_of_list_type)
@@ -146,6 +156,27 @@ notmuch_messages_move_to_next (notmuch_messages_t 
*messages)
 }
 
 void
+notmuch_messages_move_to_last (notmuch_messages_t *messages)
+{
+if (! messages-is_of_list_type)
+   return _notmuch_mset_messages_move_to_last (messages);
+
+messages-iterator = messages-list-tail;
+}
+
+void
+notmuch_messages_move_to_previous (notmuch_messages_t *messages)
+{
+if (! messages-is_of_list_type)
+   return _notmuch_mset_messages_move_to_previous (messages);
+
+if (messages-iterator == NULL)
+   return;
+
+messages-iterator = messages-iterator-prev;
+}
+
+void
 notmuch_messages_destroy (notmuch_messages_t *messages)
 {
 talloc_free (messages);
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 3b3f0eb..2269d2b 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -364,6 +364,7 @@ typedef struct _notmuch_message_list {
 struct _notmuch_messages {
 notmuch_bool_t is_of_list_type;
 notmuch_message_node_t *iterator;
+notmuch_message_list_t *list;
 };
 
 notmuch_message_list_t *
@@ -389,8 +390,17 @@ notmuch_message_t *
 _notmuch_mset_messages_get (notmuch_messages_t *messages);
 
 void
+_notmuch_mset_messages_move_to_first (notmuch_messages_t *messages);
+
+void
 _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages);
 
+void
+_notmuch_mset_messages_move_to_last (notmuch_messages_t *messages);
+
+void
+_notmuch_mset_messages_move_to_previous (notmuch_messages_t *messages);
+
 /* message.cc */
 
 void
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 0d9cb0f..753f3bb 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -645,6 +645,15 @@ notmuch_messages_valid (notmuch_messages_t *messages);
 notmuch_message_t *
 notmuch_messages_get (notmuch_messages_t *messages);
 
+/* Move the 'messages' iterator to the first message.
+ *
+ * After that the 'messages' iterator will be set to the first valid 
+ * message, so it can be use to iterate with 
+ * notmuch_messages_move_to_next.
+ */
+void
+notmuch_messages_move_to_first (notmuch_messages_t *messages);
+
 /* Move the 'messages' iterator to the next message.
  *
  * If 'messages' is already pointing at the last message then the
@@ -658,6 +667,25 @@ notmuch_messages_get (notmuch_messages_t *messages);
 void
 notmuch_messages_move_to_next (notmuch_messages_t *messages);
 
+/* Move the 'messages' iterator to the last message.
+ *
+ * After that the 'messages' iterator will be set to the last valid 
+ * message, so it can be use to iterate with 
+ * notmuch_messages_move_to_previous.
+ */
+void
+notmuch_messages_move_to_last (notmuch_messages_t *messages);
+
+/* Move the 'messages' iterator to the previous message.
+ *
+ * If 'messages' is already pointing at the first message then the
+ * iterator will be moved to a point just beyond that first message,
+ * (where notmuch_messages_valid will return FALSE and
+ * notmuch_messages_get will return NULL).
+ */
+void
+notmuch_messages_move_to_previous (notmuch_messages_t *messages);
+
 /* Destroy a notmuch_messages_t object.
  *
  * It's not strictly necessary to call this function. All memory from
diff --git a/lib/query.cc b/lib/query.cc
index 9266d35..970c35a 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -35,6 +35,7 @@ typedef struct _notmuch_mset_messages {
 notmuch_messages_t base;
 notmuch_database_t *notmuch;
 Xapian::MSetIterator iterator;
+Xapian::MSetIterator iterator_begin;
 Xapian::MSetIterator 

[notmuch] [PATCH 4/5] Added backwards iterator to threads

2010-03-20 Thread Ruben Pollan
Added the functions notmuch_threads_move_to_prevoius,
notmuch_threads_move_to_last and  notmuch_threads_move_to_first to
notmuch library. With them is possible to iterate backwards on threads.

* notmuch_threads_move_to_prevoius do the opposite than
  notmuch_threads_move_to_next, getting the threads iterator one
  position backwards.

* notmuch_threads_move_to_last move the iterator to the first last thread.

* notmuch_threads_move_to_first move the iterator to the first valid
  thread.

For it has been implemented notmuch_thread_list_t structur that stores
the thread_ids so the backwards iteration gets the thread_id in the same
order that was show on forward iteration.
---
 lib/notmuch.h |   28 +++
 lib/query.cc  |  143 -
 2 files changed, 159 insertions(+), 12 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index 753f3bb..b96b624 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -466,6 +466,15 @@ notmuch_threads_valid (notmuch_threads_t *threads);
 notmuch_thread_t *
 notmuch_threads_get (notmuch_threads_t *threads);
 
+/* Move the 'threads' iterator to the first thread.
+ *
+ * After that the 'threads' iterator will be set to the first valid 
+ * thread, so it can be use to iterate with 
+ * notmuch_threads_move_to_next.
+ */
+void
+notmuch_threads_move_to_first (notmuch_threads_t *threads);
+
 /* Move the 'threads' iterator to the next thread.
  *
  * If 'threads' is already pointing at the last thread then the
@@ -479,6 +488,25 @@ notmuch_threads_get (notmuch_threads_t *threads);
 void
 notmuch_threads_move_to_next (notmuch_threads_t *threads);
 
+/* Move the 'threads' iterator to the last thread.
+ *
+ * After that the 'threads' iterator will be set to the last valid 
+ * thread, so it can be use to iterate with 
+ * notmuch_threads_move_to_previous.
+ */
+void
+notmuch_threads_move_to_last (notmuch_threads_t *threads);
+
+/* Move the 'threads' iterator to the previous thread.
+ *
+ * If 'threads' is already pointing at the first thread then the
+ * iterator will be moved to a point just beyond that first thread,
+ * (where notmuch_threads_valid will return FALSE and
+ * notmuch_threads_get will return NULL).
+ */
+void
+notmuch_threads_move_to_previous (notmuch_threads_t *threads);
+
 /* Destroy a notmuch_threads_t object.
  *
  * It's not strictly necessary to call this function. All memory from
diff --git a/lib/query.cc b/lib/query.cc
index 44950c1..39985e7 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -39,13 +39,25 @@ typedef struct _notmuch_mset_messages {
 Xapian::MSetIterator iterator_end;
 } notmuch_mset_messages_t;
 
+typedef struct _notmuch_thread_node {
+const char *thread_id;
+struct _notmuch_thread_node *next;
+struct _notmuch_thread_node *prev;
+} notmuch_thread_node_t;
+
+typedef struct _notmuch_thread_list {
+notmuch_thread_node_t *head;
+notmuch_thread_node_t *tail;
+notmuch_thread_node_t *iterator;
+} notmuch_thread_list_t;
+
 struct _notmuch_threads {
 notmuch_query_t *query;
 GHashTable *threads;
 notmuch_messages_t *messages;
 
-/* This thread ID is our iterator state. */
-const char *thread_id;
+/* thread list with the thread_id of the showed messages */
+notmuch_thread_list_t *list;
 };
 
 notmuch_query_t *
@@ -269,6 +281,64 @@ _notmuch_mset_messages_move_to_previous 
(notmuch_messages_t *messages)
 }
 }
 
+static void
+_notmuch_thread_list_create (notmuch_thread_list_t *list, const char 
*thread_id)
+{
+list-head = talloc (list, notmuch_thread_node_t);
+list-tail = list-head;
+list-iterator = list-head;
+list-iterator-thread_id = thread_id;
+list-iterator-next = NULL;
+list-iterator-prev = NULL;
+}
+
+static void
+_notmuch_thread_list_append (notmuch_thread_list_t *list, const char 
*thread_id)
+{
+list-tail-next = talloc (list, notmuch_thread_node_t);
+list-iterator = list-tail-next;
+list-iterator-thread_id = thread_id;
+list-iterator-next = NULL;
+list-iterator-prev = list-tail;
+list-tail = list-iterator;
+}
+
+static const char *
+_notmuch_thread_list_get_id (notmuch_thread_list_t *list)
+{
+return list-iterator-thread_id;
+}
+
+static notmuch_bool_t
+_notmuch_thread_list_valid (notmuch_thread_list_t *list)
+{
+return (list-iterator != NULL);
+}
+
+static void
+_notmuch_thread_list_move_to_first (notmuch_thread_list_t *list)
+{
+list-iterator = list-head;
+}
+
+static void
+_notmuch_thread_list_move_to_next (notmuch_thread_list_t *list)
+{
+list-iterator = list-iterator-next;
+}
+
+static void
+_notmuch_thread_list_move_to_last (notmuch_thread_list_t *list)
+{
+list-iterator = list-tail;
+}
+
+static void
+_notmuch_thread_list_move_to_previous (notmuch_thread_list_t *list)
+{
+list-iterator = list-iterator-prev;
+}
+
 /* Glib objects force use to use a talloc destructor as well, (but not
  * nearly as ugly as the for messages due to C++ objects). At
  * this point, 

[notmuch] [PATCH 3/5] Move the logic of threads iterator out of 'valid'

2010-03-20 Thread Ruben Pollan
The logic of notmuch_threads_move_to_next iterator was on
notmuch_threads_valid function. Now notmuch_threads_valid just check if
the iterator is valid and is notmuch_threads_move_to_next wich actually
update the iterator.
---
 lib/query.cc |   47 ---
 1 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/lib/query.cc b/lib/query.cc
index 970c35a..44950c1 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -285,6 +285,7 @@ notmuch_threads_t *
 notmuch_query_search_threads (notmuch_query_t *query)
 {
 notmuch_threads_t *threads;
+notmuch_message_t *message;
 
 threads = talloc (query, notmuch_threads_t);
 if (threads == NULL)
@@ -296,7 +297,10 @@ notmuch_query_search_threads (notmuch_query_t *query)
 
 threads-messages = notmuch_query_search_messages (query);
 
-threads-thread_id = NULL;
+message = notmuch_messages_get (threads-messages);
+threads-thread_id = notmuch_message_get_thread_id (message);
+g_hash_table_insert (threads-threads,
+ xstrdup (threads-thread_id), NULL);
 
 talloc_set_destructor (threads, _notmuch_threads_destructor);
 
@@ -312,10 +316,25 @@ notmuch_query_destroy (notmuch_query_t *query)
 notmuch_bool_t
 notmuch_threads_valid (notmuch_threads_t *threads)
 {
-notmuch_message_t *message;
+return (threads-thread_id != NULL);
+}
 
-if (threads-thread_id)
-   return TRUE;
+notmuch_thread_t *
+notmuch_threads_get (notmuch_threads_t *threads)
+{
+if (! notmuch_threads_valid (threads))
+   return NULL;
+
+return _notmuch_thread_create (threads-query,
+  threads-query-notmuch,
+  threads-thread_id,
+  threads-query-query_string);
+}
+
+void
+notmuch_threads_move_to_next (notmuch_threads_t *threads)
+{
+notmuch_message_t *message;
 
 while (notmuch_messages_valid (threads-messages))
 {
@@ -330,33 +349,15 @@ notmuch_threads_valid (notmuch_threads_t *threads)
g_hash_table_insert (threads-threads,
 xstrdup (threads-thread_id), NULL);
notmuch_messages_move_to_next (threads-messages);
-   return TRUE;
+   return;
}
 
notmuch_messages_move_to_next (threads-messages);
 }
 
 threads-thread_id = NULL;
-return FALSE;
-}
-
-notmuch_thread_t *
-notmuch_threads_get (notmuch_threads_t *threads)
-{
-if (! notmuch_threads_valid (threads))
-   return NULL;
-
-return _notmuch_thread_create (threads-query,
-  threads-query-notmuch,
-  threads-thread_id,
-  threads-query-query_string);
 }
 
-void
-notmuch_threads_move_to_next (notmuch_threads_t *threads)
-{
-threads-thread_id = NULL;
-}
 
 void
 notmuch_threads_destroy (notmuch_threads_t *threads)
-- 
1.7.0

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


[notmuch] [PATCH 5/5] Added backwards iterator to tags

2010-03-20 Thread Ruben Pollan
Added the functions notmuch_tags_move_to_prevoius,
notmuch_tags_move_to_last and  notmuch_tags_move_to_first to notmuch
library. With them is possible to iterate backwards on tags.

* notmuch_tags_move_to_prevoius do the opposite than
  notmuch_tags_move_to_next, getting the tags iterator one
  position backwards.

* notmuch_tags_move_to_last move the iterator to the first last tag.

* notmuch_tags_move_to_first move the iterator to the first valid tag.
---
 lib/notmuch.h |   28 
 lib/tags.c|   21 +
 2 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index b96b624..dc668dc 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -1022,6 +1022,15 @@ notmuch_tags_valid (notmuch_tags_t *tags);
 const char *
 notmuch_tags_get (notmuch_tags_t *tags);
 
+/* Move the 'tags' iterator to the first tag.
+ *
+ * After that the 'tags' iterator will be set to the first valid 
+ * tag, so it can be use to iterate with 
+ * notmuch_tags_move_to_next.
+ */
+void
+notmuch_tags_move_to_first (notmuch_tags_t *tags);
+
 /* Move the 'tags' iterator to the next tag.
  *
  * If 'tags' is already pointing at the last tag then the iterator
@@ -1035,6 +1044,25 @@ notmuch_tags_get (notmuch_tags_t *tags);
 void
 notmuch_tags_move_to_next (notmuch_tags_t *tags);
 
+/* Move the 'tags' iterator to the last tag.
+ *
+ * After that the 'tags' iterator will be set to the last valid 
+ * tag, so it can be use to iterate with 
+ * notmuch_tags_move_to_previous.
+ */
+void
+notmuch_tags_move_to_last (notmuch_tags_t *tags);
+
+/* Move the 'tags' iterator to the previous tag.
+ *
+ * If 'tags' is already pointing at the first tag then the
+ * iterator will be moved to a point just beyond that first tag,
+ * (where notmuch_tags_valid will return FALSE and
+ * notmuch_tags_get will return NULL).
+ */
+void
+notmuch_tags_move_to_previous (notmuch_tags_t *tags);
+
 /* Destroy a notmuch_tags_t object.
  *
  * It's not strictly necessary to call this function. All memory from
diff --git a/lib/tags.c b/lib/tags.c
index 8fe4a3f..9c9a897 100644
--- a/lib/tags.c
+++ b/lib/tags.c
@@ -105,6 +105,12 @@ notmuch_tags_get (notmuch_tags_t *tags)
 }
 
 void
+notmuch_tags_move_to_first (notmuch_tags_t *tags)
+{
+tags-iterator = g_list_first (tags-tags);
+}
+
+void
 notmuch_tags_move_to_next (notmuch_tags_t *tags)
 {
 if (tags-iterator == NULL)
@@ -114,6 +120,21 @@ notmuch_tags_move_to_next (notmuch_tags_t *tags)
 }
 
 void
+notmuch_tags_move_to_last (notmuch_tags_t *tags)
+{
+tags-iterator = g_list_last (tags-tags);
+}
+
+void
+notmuch_tags_move_to_previous (notmuch_tags_t *tags)
+{
+if (tags-iterator == NULL)
+   return;
+
+tags-iterator = tags-iterator-prev;
+}
+
+void
 notmuch_tags_destroy (notmuch_tags_t *tags)
 {
 talloc_free (tags);
-- 
1.7.0

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


Re: [notmuch] Tag search peculiarities

2010-03-20 Thread Ben Gamari
On Thu, 18 Mar 2010 15:27:12 +0100, Sandra Snan sandra.s...@handgranat.org 
wrote:
 Hey, Ben.
 Ben Gamari bgamari.f...@gmail.com wrote:
  notmuch tag -new tag:new and tag:list notmuch tag -new +inbox tag:new
 
 Is there a new line between the calls? Like:
 notmuch tag -new tag:new and tag:list # removes new from list
 notmuch tag -new +inbox tag:new # replaces those that still are new with inbox
 
Eh? They are two separate notmuch invocations.

  However, I found that mailing list traffic was still getting through.
 
 What do you mean by “through”? Do you mean that there still are
 messages tagged both inbox and list? Even though you can’t search for
 them?
 
Yeah, poor choice of words. After the two commands above ran, my mailing list
messages were tagged with new, inbox.

 If a message is tagged both inbox and list, but not new then the two
 lines of your script that you posted so far wouldn’t change it, and it
 would still bo both inbox and list.
 
 It’s risky being so dependent on the new tag.
 
Eh? I fail to see why. It's no more risky than depending on the inbox tag.

  After investigating further, I found that any query in the form of 
  tag:inbox
  and tag:$TAG would return no results. Strangely, all other combinations of 
  tag
  searches (i.e. tag:lkml and tag:unread) seem to work just fine.
  
  Has anyone else noticed this sort of behavior? Does the inbox tag have some
  special signifigance that I should know of?
 
 Yes, many versions of the reading client (for example, the version of
 notmuch.el that ships with the notmuch package in debian) remove the
 inbox tag from messages once you scroll past them or when you press
 the key that’s bound to notmuch-show-archive-thread (default is “a”).
 
I guess I should have been more explicit. I meant in notmuch itself, not the
clients.

  Is my index just FUBAR? (the ladder would be very strange
  considering it's only a few days old and I can't think of any
  crashes, etc. that might have corrupted it) Any ideas for debugging?
 
 Add the tags manually to a few messages, search for them again, and be
 sure to not run your tagging script while looking at this problem.
 
 Michal’s tip, looking at a few lines of notmuch dump, is a good idea
 too. Notmuch dump is fast, so don’t be afraid (notmuch restore on the
 other hand… but even that completes fast enough.)
 
 I’ve often been surprised at weird tag situations then realized that
 it was old versions of my own scripts that had ran in the background
 and I’ve forgotten about it.
 
Indeed. Hopefully it will be something so simple. I'm currently blissfully
unaware of the internals of Xapian, and would really like to remain that way.

Thanks,

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


Re: [notmuch] Tag search peculiarities

2010-03-20 Thread Sandra Snan
On Sat, 20 Mar 2010 16:09:00 -0700 (PDT), Ben Gamari bgamari.f...@gmail.com 
wrote:
 On Thu, 18 Mar 2010 15:27:12 +0100, Sandra Snan sandra.s...@handgranat.org 
 wrote:
  Hey, Ben.
  Ben Gamari bgamari.f...@gmail.com wrote:
   notmuch tag -new tag:new and tag:list notmuch tag -new +inbox tag:new
  
  Is there a new line between the calls? Like:
  notmuch tag -new tag:new and tag:list # removes new from list
  notmuch tag -new +inbox tag:new # replaces those that still are new with 
  inbox
  
 Eh? They are two separate notmuch invocations.

In my mail (quoted above) it showed up as one single line, a single
invocation. Guess there was mail problem somewhere. Thanks for the 
clarification.

 Yeah, poor choice of words. After the two commands above ran, my mailing list
 messages were tagged with new, inbox.

And not list? Huh. Does seem weird that after explicitly replacing new
with inbox, as you did, you still have them new.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[notmuch] Using notmuch as an address book for tab-completion

2010-03-20 Thread Jesse Rosenthal
Dear All,

There was some talk on IRC ages ago about using notmuch as an
address-book for tab-completion in emacs message mode. Thanks to some
great recent work (Ingmar Vanhassel's shared lib and Sebastians's
cnotmuch python lib) I have been able to take a first step in that
direction. I've written a python script (with some help and suggestions
from spaetz) which can perform the address-book functionality, and a
backend for emacs's EUDC address-lookup functionality to access the
script.

They are available by the following commands:

git clone http://jkr.acm.jhu.edu/git/notmuch_addresses.git
git clone http://jkr.acm.jhu.edu/git/notmuch_eudc.git

Remember, neither of these will do you much good with the shared lib and
cnotmuch installed.

At the moment, the script works by search addresses that you have
written to (or CC'd or BCC'd) in the past. This seems like a good
utility-speed tradeoff, but it would be easy to hack the script to
search a different set of messages. Give three letters (it looks through
first names, last names, and email addresses) it returns results from my
12K messages in well under a second. 

The responses are sorted by frequency, and each email address is
associated with the most frequently used real name (null real-names are
avoided, unless they're the only option).

The script can be run from the command line by:
$ python notmuch_addresses.py query

To get tab completion from emacs, you have to install the script into
your path, make it executable, and then put my eudcb-notmuch.el file
into your load path (you should byte-compile it too). DON'T CHANGE THE
TITLE OF THE .EL FILE! EUDC looks for a specific title based on
protocol.

Then add the following to your .emacs:

(eudc-set-server localhost 'notmuch t)
(setq eudc-server-hotlist '((localhost . notmuch)))
(setq eudc-inline-expansion-servers 'hotlist)

if you wish to use BBDB too (likely before you use notmuch), then
you should use something like this:

(eudc-set-server localhost 'bbdb t)
(eudc-protocol-set 'eudc-inline-expansion-format 
   '(%s %s %s firstname lastname net)
   'bbdb)
(eudc-set-server localhost 'notmuch t)
(setq eudc-server-hotlist '((localhost . bbdb)
(localhost . notmuch)))
(setq eudc-inline-expansion-servers 'hotlist)

That should do it. Please let me know if it works for you.

(For those of you who care, eudcb-notmuch.el has a few hacky bits to
hide the fact that notmuch really isn't an address book. That is, it
doesn't know the difference between names and email addresses. So
everything you enter just goes in as one string, which I call name.
Back-end stuff, but if you're looking through the code, that might make
a few things clearer.)

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


Re: [notmuch] Using notmuch as an address book for tab-completion

2010-03-20 Thread Jesse Rosenthal
Normally, I wouldn't respond to myself to fix a typo, but this seemed
important.

 Remember, neither of these will do you much good with the shared lib and
 cnotmuch installed.

I meant, of course, that neither would do you much good *WITHOUT* the
shared lib and cnotmuch installed.

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