[notmuch] lots of emacs mode enhancements
On Fri, 20 Nov 2009 00:26:33 -0800, Alexander Botero-Lowry wrote: > I've just been diving into the elisp, and have added a bunch of useful > features. This is fantastic stuff, Alex. Thanks so much for working on it. (And I'm sorry it took me a while before I got around to reviewing it. Hopefully I'll be more responsive when I'm done travelling in a couple of days. > 1) buttonized citation and signature expanders and made them locally > collapsable instead of globally > 2) fixed an annoying warning about cons not being a face name > 3) made header names bold to make it easier to distingush them from > their value I really like the bold headers. And I can tell that the buttonization is going to be very nice. But I can't actually get it to work completely. I first clicked[*] on a signature to make it visible, which worked find. But then clicking on it again I got "buffer is read-only" and it wouldn't hide. At that point I couldn't get any of the other buttons to make things visible either. So, being unwilling to have hidden content that I can't make visible, I can't merge this work in its current state. If you can't replicate the bug, let me know and I'll try to look closer at what's going on. > (this could take some cleanup to remove > the global key-map binding or make it work again) Obviously, we should not have a keybinding that doesn't work. But I'd be glad to just remove it---if we can do local expansion I don't see a big reason to have global expansion. At least for things like citations and signature. For message bodies, that's different, so I can imagine having an "expand all" keybinding for them. Meanwhile, the feature that I *will* want is something to make it easy to use the keyboard alone to show/hide hidden parts. What I want is for TAB to advance to the next button, so that then I can just press RET on it to toggle it. > My next target is to carry the buttonization through to threads and > headers, and then I'm going to look into doing better mime-handling in > general. Great. I'll look forward to that. > also, RFP includes a -p argument that gives a patch :) Very nice. It's appreciated. -Carl [*] Any reason we can't make button 1 do this instead of button 2? That should be more intuitive, and at worst it means that the text on the button itself is hard to select, which shouldn't be an option.
[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags
On Tue, 17 Nov 2009 13:32:45 -0800, Keith Packard wrote: > When closing a thread view, mark the thread as archived by removing > the "inbox" tag, and for the 'x' variant, the "unread" tag as well, > then kill the buffer and update the search window view as well. I'm starting to come around to this patch, Keith. :-) I think one thing we're going to really need is a better help message for presenting the keybindings. The function names are all really confusing, (the "notmuch-show" prefix doesn't help). So what I'd really like is something that displays the keybinding and the first line of the documentation of a function, rather than the function name itself. > This makes 'x' much the same as 'a', but instead of taking you to the > next message, it takes you back to the search window instead. Except that the patch also reverses the current behavior of "a" and "A". That should be a separate patch anyway, but I'm also not sure that I like it. I like that the command that takes the extra effort of pressing shift is the command that does *more*, (removing both "unread" and "inbox"), rather than the command that does *less*. -Carl
[notmuch] lots of emacs mode enhancements
On Mon, 23 Nov 2009 00:11:22 +0100, Carl Worth wrote: > On Fri, 20 Nov 2009 00:26:33 -0800, Alexander Botero-Lowry at gmail.com> wrote: > I really like the bold headers. And I can tell that the buttonization is > going to be very nice. But I can't actually get it to work completely. I > first clicked[*] on a signature to make it visible, which worked > find. But then clicking on it again I got "buffer is read-only" and it > wouldn't hide. At that point I couldn't get any of the other buttons to > make things visible either. This was simply a re-display bug which Alexander fixed. And he also changed the buttons from button-2 to button-1. I really like the final result, so it's pushed now. Citations and signatures can now be expanded locally! It is slightly harder to do this with the keyboard now. You have to actually position point right on the button. This is just a temporary thing, as I want to add a TAB binding to move point to the next button. So keyboard-lovers, don't worry, notmuch (at least the emacs interface) will always be very friendly for keyboard use (excepting temporary lapses like this current one). -Carl
[notmuch] [PATCH] Support for printing file paths in new command
For very large mail boxes, it is desirable to know which files are being processed e.g. when a crash occurs to know which one was the cause. Also, it may be interesting to have a better idea of how the operation is progressing when processing mailboxes with big messages. This patch adds support for printing messages as they are processed by "notmuch new": * The "new" command now supports a "--verbose" flag. * When running in verbose mode, the file path of the message about to be processed is printed in the following format: current/total: /path/to/message/file Where "current" is the number of messages processed so far and "total" is the total count of files to be processed. * The status line is erased using an ANSI sequence "\033[K" (erase current line from the cursor to the end of line) each time it is refreshed. This should not pose a problem because nearly every terminal supports it. * When output is not being sent to a terminal, then each file processed is printed in a new line and ANSI escapes are not used at all. * The signal handler for SIGALRM and the timer are not enabled when running in verbose mode, because we are already printing progress with each file, periodical reports are not neccessary. --- notmuch-client.h |2 ++ notmuch-new.c| 32 +--- notmuch.c| 11 +-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index ea77686..4fe182e 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -74,6 +74,8 @@ typedef void (*add_files_callback_t) (notmuch_message_t *message); typedef struct { int ignore_read_only_directories; int saw_read_only_directory; +int output_is_a_tty; +int verbose; int total_files; int processed_files; diff --git a/notmuch-new.c b/notmuch-new.c index 0dd2784..b5c6cc6 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -179,6 +179,19 @@ add_files_recursive (notmuch_database_t *notmuch, if (path_dbtime == 0 || st->st_mtime > path_dbtime) { state->processed_files++; + if (state->verbose) { + if (state->output_is_a_tty) + printf("\r\033[K"); + + printf ("%i/%i: %s", + state->processed_files, + state->total_files, + next); + + putchar((state->output_is_a_tty) ? '\r' : '\n'); + fflush (stdout); + } + status = notmuch_database_add_message (notmuch, next, &message); switch (status) { /* success */ @@ -275,7 +288,7 @@ add_files (notmuch_database_t *notmuch, } /* Setup our handler for SIGALRM */ -if (isatty (fileno (stdout)) && ! debugger_is_active ()) { +if (state->output_is_a_tty && ! debugger_is_active () && ! state->verbose) { memset (&action, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigalrm; sigemptyset (&action.sa_mask); @@ -296,6 +309,7 @@ add_files (notmuch_database_t *notmuch, /* Now stop the timer. */ if (timer_is_active) { + /* Now stop the timer. */ timerval.it_interval.tv_sec = 0; timerval.it_interval.tv_usec = 0; timerval.it_value.tv_sec = 0; @@ -380,8 +394,7 @@ count_files (const char *path, int *count) } int -notmuch_new_command (void *ctx, -unused (int argc), unused (char *argv[])) +notmuch_new_command (void *ctx, int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; @@ -393,6 +406,19 @@ notmuch_new_command (void *ctx, const char *db_path; char *dot_notmuch_path; struct sigaction action; +int i; + +add_files_state.verbose = 0; +add_files_state.output_is_a_tty = isatty (fileno (stdout)); + +for (i = 0; i < argc && argv[i][0] == '-'; i++) { + if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) { + add_files_state.verbose = 1; + } else { + fprintf (stderr, "Unrecognized option: %s\n", argv[i]); + return 1; + } +} /* Setup our handler for SIGINT */ memset (&action, 0, sizeof (struct sigaction)); diff --git a/notmuch.c b/notmuch.c index 5cc8e4c..8cb1310 100644 --- a/notmuch.c +++ b/notmuch.c @@ -107,8 +107,8 @@ command_t commands[] = { "\t\tInvoking notmuch with no command argument will run setup if\n" "\t\tthe setup command has not previously been completed." }, { "new", notmuch_new_command, - NULL, - "Find and import new messages to the notmuch database.", + "[--verbose]", + "\t\tFind and import new messages to the notmuch database.", "\t\tScans all sub-directories of the mail directory, performing\n" "\t\tfull-text indexing on new messages that are found. Each new\n" "\t\tmessage will be tagged as both \"inbox\" and \"unread\".
[notmuch] [PATCH 3/3] notmuch.el: Select tag names with completion.
Several commands ask the user for a tag name. With this feature the user can just press tab and Emacs automatically retrieves the list of all existing tags from notmuch database with 'notmuch search-tags' and presents a completion buffer to the user. This feature is very useful for users who have a large number of tags because it saves typing and minimizes the risk of typos. Signed-off-by: Jan Janak --- notmuch.el | 22 +- 1 files changed, 17 insertions(+), 5 deletions(-) diff --git a/notmuch.el b/notmuch.el index 5927737..b6be395 100644 --- a/notmuch.el +++ b/notmuch.el @@ -139,6 +139,13 @@ within the current window." (or (memq prop buffer-invisibility-spec) (assq prop buffer-invisibility-spec) +(defun notmuch-select-tag-with-completion (prompt) + (let ((tag-list +(with-output-to-string + (with-current-buffer standard-output +(call-process notmuch-command nil t nil "search-tags") +(completing-read prompt (split-string tag-list "\n+" t) nil nil nil))) + (defun notmuch-show-next-line () "Like builtin `next-line' but ensuring we end on a visible character. @@ -202,7 +209,8 @@ Unlike builtin `next-line' this version accepts no arguments." (defun notmuch-show-add-tag (&rest toadd) "Add a tag to the current message." - (interactive "sTag to add: ") + (interactive + (list (notmuch-select-tag-with-completion "Tag to add: "))) (apply 'notmuch-call-notmuch-process (append (cons "tag" (mapcar (lambda (s) (concat "+" s)) toadd)) @@ -211,7 +219,8 @@ Unlike builtin `next-line' this version accepts no arguments." (defun notmuch-show-remove-tag (&rest toremove) "Remove a tag from the current message." - (interactive "sTag to remove: ") + (interactive + (list (notmuch-select-tag-with-completion "Tag to remove: "))) (let ((tags (notmuch-show-get-tags))) (if (intersection tags toremove :test 'string=) (progn @@ -970,12 +979,14 @@ and will also appear in a buffer named \"*Notmuch errors*\"." (split-string (buffer-substring beg end)) (defun notmuch-search-add-tag (tag) - (interactive "sTag to add: ") + (interactive + (list (notmuch-select-tag-with-completion "Tag to add: "))) (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id)) (notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string< (defun notmuch-search-remove-tag (tag) - (interactive "sTag to remove: ") + (interactive + (list (notmuch-select-tag-with-completion "Tag to remove: "))) (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id)) (notmuch-search-set-tags (delete tag (notmuch-search-get-tags @@ -1061,7 +1072,8 @@ current search results AND the additional query string provided." Runs a new search matching only messages that match both the current search results AND that are tagged with the given tag." - (interactive "sFilter by tag: ") + (interactive + (list (notmuch-select-tag-with-completion "Filter by tag: "))) (notmuch-search (concat notmuch-search-query-string " and tag:" tag) notmuch-search-oldest-first)) (defun notmuch () -- 1.6.3.3
[notmuch] [PATCH 2/3] notmuch: New command 'search-tags'.
This is a new notmuch command that can be used to search for all tags found in the database. The resulting list is alphabetically sorted. The primary use-case for this new command is to provide the tag completion feature in Emacs (and other interfaces). Signed-off-by: Jan Janak --- Makefile.local|1 + notmuch-client.h |3 ++ notmuch-search-tags.c | 71 + notmuch.c |6 4 files changed, 81 insertions(+), 0 deletions(-) create mode 100644 notmuch-search-tags.c diff --git a/Makefile.local b/Makefile.local index 2828659..d8f7906 100644 --- a/Makefile.local +++ b/Makefile.local @@ -12,6 +12,7 @@ notmuch_client_srcs = \ notmuch-reply.c \ notmuch-restore.c \ notmuch-search.c\ + notmuch-search-tags.c \ notmuch-setup.c \ notmuch-show.c \ notmuch-tag.c \ diff --git a/notmuch-client.h b/notmuch-client.h index ea77686..c6142b5 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -114,6 +114,9 @@ notmuch_show_command (void *ctx, int argc, char *argv[]); int notmuch_tag_command (void *ctx, int argc, char *argv[]); +int +notmuch_search_tags_command (void *ctx, int argc, char *argv[]); + const char * notmuch_time_relative_date (const void *ctx, time_t then); diff --git a/notmuch-search-tags.c b/notmuch-search-tags.c new file mode 100644 index 000..1201165 --- /dev/null +++ b/notmuch-search-tags.c @@ -0,0 +1,71 @@ +/* notmuch - Not much of an email program, (just index and search) + * + * Copyright ?? 2009 Carl Worth + * Copyright ?? 2009 Jan Janak + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ . + * + * Author: Jan Janak + */ + +#include "notmuch-client.h" + +static int +list_all_tags (notmuch_database_t* db) +{ +notmuch_tags_t* tags; +const char* t; + +if ((tags = notmuch_database_get_all_tags (db)) == NULL) { + fprintf (stderr, "Error while obtaining tags from the database.\n"); + return 1; +} + +while((t = notmuch_tags_get (tags))) { + printf ("%s\n", t); + notmuch_tags_advance (tags); +} + +notmuch_tags_destroy (tags); +return 0; +} + +int +notmuch_search_tags_command (void *ctx, int argc, char *argv[]) +{ +notmuch_config_t *config; +notmuch_database_t *db; + +config = NULL; +db = NULL; + +if ((config = notmuch_config_open (ctx, NULL, NULL)) == NULL) { + goto error; +} + +db = notmuch_database_open (notmuch_config_get_database_path (config), + NOTMUCH_DATABASE_MODE_READ_ONLY); +if (db == NULL) { + goto error; +} + +if (list_all_tags (db) != 0) goto error; + +notmuch_database_close (db); +return 0; + +error: +if (db) notmuch_database_close (db); +return 1; +} diff --git a/notmuch.c b/notmuch.c index 5cc8e4c..b1d7cf9 100644 --- a/notmuch.c +++ b/notmuch.c @@ -230,6 +230,12 @@ command_t commands[] = { "\t\tSo if you've previously been using sup for mail, then the\n" "\t\t\"notmuch restore\" command provides you a way to import\n" "\t\tall of your tags (or labels as sup calls them)." }, +{ "search-tags", notmuch_search_tags_command, + NULL, + "List all tags found in the database.", + "\t\tThis command returns an alphabetically sorted list of all tags\n" + "\t\tthat are present in the database. In other words, the resulting\n" + "\t\tlist is a collection of all tags from all messages." }, { "help", notmuch_help_command, "[]", "\t\tThis message, or more detailed help for the named command.", -- 1.6.3.3
[notmuch] [PATCH 1/3] notmuch: New function to retrieve all tags from the database.
This patch adds a new function called notmuch_database_get_all_tags which can be used to obtain a list of all tags from the database (in other words, the list contains all tags from all messages). The function produces an alphabetically sorted list. To add support for the new function, we rip the guts off of notmuch_message_get_tags and put them in a new generic function called _notmuch_convert_tags. The generic function takes a Xapian::TermIterator as argument and uses the iterator to find tags. This makes the function usable with different Xapian objects. Function notmuch_message_get_tags is then reimplemented to call the generic function with message->doc.termlist_begin() as argument. Similarly, we implement notmuch_message_database_get_all_tags, the function calls the generic function with db->xapian_db->allterms_begin() as argument. Finally, notmuch_database_get_all_tags is exported through lib/notmuch.h Signed-off-by: Jan Janak --- lib/database-private.h | 13 + lib/database.cc| 43 +++ lib/message.cc | 34 +++--- lib/notmuch.h | 10 ++ 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/lib/database-private.h b/lib/database-private.h index 5f178f3..37f9bf8 100644 --- a/lib/database-private.h +++ b/lib/database-private.h @@ -34,4 +34,17 @@ struct _notmuch_database { Xapian::TermGenerator *term_gen; }; +/* Convert tags from Xapian internal format to notmuch format. + * + * The function gets a TermIterator as argument and uses that iterator to find + * all tag terms in the object. The tags are then converted to a + * notmuch_tags_t list and returned. The function needs to allocate memory for + * the resulting list and it uses the argument ctx as talloc context. + * + * The function returns NULL on failure. + */ +notmuch_tags_t * +_notmuch_convert_tags (void *ctx, Xapian::TermIterator &i, + Xapian::TermIterator &end); + #endif diff --git a/lib/database.cc b/lib/database.cc index 2c90019..5d2add7 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -1026,3 +1026,46 @@ notmuch_database_add_message (notmuch_database_t *notmuch, return ret; } + +notmuch_tags_t * +_notmuch_convert_tags (void *ctx, Xapian::TermIterator &i, + Xapian::TermIterator &end) +{ +const char *prefix = _find_prefix ("tag"); +notmuch_tags_t *tags; +std::string tag; + +/* Currently this iteration is written with the assumption that + * "tag" has a single-character prefix. */ +assert (strlen (prefix) == 1); + +tags = _notmuch_tags_create (ctx); +if (unlikely (tags == NULL)) + return NULL; + +i.skip_to (prefix); + +while (i != end) { + tag = *i; + + if (tag.empty () || tag[0] != *prefix) + break; + + _notmuch_tags_add_tag (tags, tag.c_str () + 1); + + i++; +} + +_notmuch_tags_prepare_iterator (tags); + +return tags; +} + +notmuch_tags_t * +notmuch_database_get_all_tags (notmuch_database_t *db) +{ +Xapian::TermIterator i, end; +i = db->xapian_db->allterms_begin(); +end = db->xapian_db->allterms_end(); +return _notmuch_convert_tags(db, i, end); +} diff --git a/lib/message.cc b/lib/message.cc index 017c47b..d27ea92 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -459,38 +459,10 @@ notmuch_message_get_date (notmuch_message_t *message) notmuch_tags_t * notmuch_message_get_tags (notmuch_message_t *message) { -const char *prefix = _find_prefix ("tag"); Xapian::TermIterator i, end; -notmuch_tags_t *tags; -std::string tag; - -/* Currently this iteration is written with the assumption that - * "tag" has a single-character prefix. */ -assert (strlen (prefix) == 1); - -tags = _notmuch_tags_create (message); -if (unlikely (tags == NULL)) - return NULL; - -i = message->doc.termlist_begin (); -end = message->doc.termlist_end (); - -i.skip_to (prefix); - -while (i != end) { - tag = *i; - - if (tag.empty () || tag[0] != *prefix) - break; - - _notmuch_tags_add_tag (tags, tag.c_str () + 1); - - i++; -} - -_notmuch_tags_prepare_iterator (tags); - -return tags; +i = message->doc.termlist_begin(); +end = message->doc.termlist_end(); +return _notmuch_convert_tags(message, i, end); } void diff --git a/lib/notmuch.h b/lib/notmuch.h index a61cd02..e2f1398 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -280,6 +280,16 @@ notmuch_message_t * notmuch_database_find_message (notmuch_database_t *database, const char *message_id); +/* Return a list of all tags found in the database. + * + * This function creates a list of all tags found in the database. The + * resulting list contains all tags from all messages found in the database. + * + * On error this function returns NULL. + */ +notmuch_tags_t * +notmuch_d
[notmuch] [PATCH] Support for printing file paths in new command
On Sat, 21 Nov 2009 01:17:18 +0100, Adrian Perez wrote: > For very large mail boxes, it is desirable to know which files are being > processed e.g. when a crash occurs to know which one was the cause. Also, > it may be interesting to have a better idea of how the operation is > progressing when processing mailboxes with big messages. > > This patch adds support for printing messages as they are processed by > "notmuch new": Hey, that's pretty nice. I've pushed this now, (and I'm almost tempted to make it the default...). -Carl
[notmuch] [PATCH] Quote file names passed to the shell
On Sat, 21 Nov 2009 03:37:54 +0100, Jed Brown wrote: > Prior to this, notmuch-show-pipe-message could not handle file names > with spaces and similar. Thanks for the fix, Jed. This is pushed. -Carl
[notmuch] [PATCH] Insert signature into replies
On Fri, 20 Nov 2009 20:57:35 -0800, Keith Packard wrote: > When you compose a new message, message mode carefully inserts your > mail signature at the bottom of the message; as notmuch constructs the > reply all by itself, this doesn't happen then. Use the message mode > function 'message-insert-signature' to add that to reply buffers. Very nice. And look below! It works too. :-) Pushed -Carl -- Searching for an email solution? There's not much out there. http://notmuchmail.org
[notmuch] [PATCH] Support for printing file paths in new command
On Mon, 23 Nov 2009 01:24:09 +0100, Carl wrote: > On Sat, 21 Nov 2009 01:17:18 +0100, Adrian Perez wrote: > > For very large mail boxes, it is desirable to know which files are being > > processed e.g. when a crash occurs to know which one was the cause. Also, > > it may be interesting to have a better idea of how the operation is > > progressing when processing mailboxes with big messages. > > > > This patch adds support for printing messages as they are processed by > > "notmuch new": > > Hey, that's pretty nice. Thanks! As a small improvement, I will send another patch in a while, which will avoid sending ANSI escapes when output is not a terminal, and print one file path per line in that case. > I've pushed this now, (and I'm almost tempted to make it the > default...). IMHO it would be nice to have the messages-per-second information as well in verbose mode before making it the default. I think I could cook up a patch for that, but printing messages-per-second would mean calling gettimeofday() for each processed file. Do you think that will be acceptable from a performance POV? (Of course using silent mode would still only call it once per second). Regards, -- Adrian Perez de Castro Igalia - Free Software Engineering -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/aba0f79c/attachment.pgp>
[notmuch] [PATCH] ANSI escapes in "new" only when output is a tty
When running "notmuch new --verbose", ANSI escapes are used. This may not be desirable when the output of the command is *not* being sent to a terminal (e.g. when piping output into another command). In that case each file processed is printed in a new line and ANSI escapes are not used at all. --- notmuch-client.h |1 + notmuch-new.c| 12 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index f105c8b..4fe182e 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -74,6 +74,7 @@ typedef void (*add_files_callback_t) (notmuch_message_t *message); typedef struct { int ignore_read_only_directories; int saw_read_only_directory; +int output_is_a_tty; int verbose; int total_files; diff --git a/notmuch-new.c b/notmuch-new.c index a2b30bd..8172b49 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -180,10 +180,15 @@ add_files_recursive (notmuch_database_t *notmuch, state->processed_files++; if (state->verbose) { - printf ("\r\033[K%i/%i: %s\r", + if (state->output_is_a_tty) + printf("\r\033[K"); + + printf ("%i/%i: %s", state->processed_files, state->total_files, next); + + putchar((state->output_is_a_tty) ? '\r' : '\n'); fflush (stdout); } @@ -282,9 +287,7 @@ add_files (notmuch_database_t *notmuch, return NOTMUCH_STATUS_FILE_ERROR; } -if (isatty (fileno (stdout)) && ! debugger_is_active () - && ! state->verbose) -{ +if (state->output_is_a_tty && ! debugger_is_active () && ! state->verbose) { /* Setup our handler for SIGALRM */ memset (&action, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigalrm; @@ -405,6 +408,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) int i; add_files_state.verbose = 0; +add_files_state.output_is_a_tty = isatty (fileno (stdout)); for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) { -- 1.6.5.2
[notmuch] search-tags and tag completion in notmuch.el
Hello, The three patches I sent to the list a couple of minutes ago is another revision of the patches that I had sent earlier. The first two patches implement support for 'notmuch search-tags'. The last patch adds support for tag completion to notmuch.el using the new command. Right now 'notmuch search-tags' can only list all tags from the database, it does not support search-terms yet (i.e. it cannot list tags for a restricted set of messages or threads), but I am working on that feature and I'm gonna send another patch implementing that soon. I think sending more smaller incremental patches makes it easier to review them (and for me personally it is easier to keep them up-to-date on top of moving Carl's git repository). I considered implementing 'notmuch search --output=tags' (as we discussed in another email), but it turned out that: * Having 'notmuch search-tags' would be consistent with Carl's 'notmuch search-messages'. * 'notmuch search' supports other command line options (--first, --max-threads, --sort) and these would only work when the user uses the command to search for messages. They would probably be useless if we use the command to search for tags and messages (well, at least some of them). Which means we would have to let the user know in the documentation, or disable some of them based on the value of the --output command line parameter, etc etc... * 'notmuch search-tags' is easier on fingers than 'notmuch search --output=tags' :-). In any case, we should probably keep it consistent with other commands and because Carl submitted 'notmuch search-messages", I did the same for tags. I'd personally prefer to use different commands for different kinds of output rather than overloading 'notmuch search' with more command line options, but it's just a personal preference. I can change the patch again if we decide that we're going to overload 'notmuch search' rather than add more commands. Comments, ideas, and suggestions are welcome! -- Jan
[notmuch] [PATCH] Handle message renames in mail spool
In order to handle message renames the following changes were deemed necessary: * Mtime check on individual files was disabled. As files may be moved around without changing their mtime, it's necessary to parse them even if they appear old in case old message was moved. mtime check on directories was kept as moving files changes mtime of directory. * If message being parsed is already found in database under different path, then this message is considered to be moved, path is updated in database and this file does not undergo further processing. Note that after applying this patch notmuch still does not handle copying files (which is harmless, database will point to the last copy of message found during 'notmuch new') and deleting files (which is more serious, as dangling entries will show up in searches). Signed-off-by: Mikhail Gusarov --- lib/database.cc | 21 +++- notmuch-new.c | 92 ++ 2 files changed, 56 insertions(+), 57 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 2c90019..d88efbe 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -990,20 +990,23 @@ notmuch_database_add_message (notmuch_database_t *notmuch, if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) { _notmuch_message_set_filename (message, filename); _notmuch_message_add_term (message, "type", "mail"); + + ret = _notmuch_database_link_message (notmuch, message, message_file); + if (ret) + goto DONE; + + date = notmuch_message_file_get_header (message_file, "date"); + _notmuch_message_set_date (message, date); + + _notmuch_message_index_file (message, filename); + } else if (strcmp(notmuch_message_get_filename(message), filename)) { + /* Message file has been moved/renamed */ + _notmuch_message_set_filename (message, filename); } else { ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; goto DONE; } - ret = _notmuch_database_link_message (notmuch, message, message_file); - if (ret) - goto DONE; - - date = notmuch_message_file_get_header (message_file, "date"); - _notmuch_message_set_date (message, date); - - _notmuch_message_index_file (message, filename); - _notmuch_message_sync (message); } catch (const Xapian::Error &error) { fprintf (stderr, "A Xapian exception occurred adding message: %s.\n", diff --git a/notmuch-new.c b/notmuch-new.c index 0dd2784..d16679c 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -174,54 +174,50 @@ add_files_recursive (notmuch_database_t *notmuch, } if (S_ISREG (st->st_mode)) { - /* If the file hasn't been modified since the last -* add_files, then we need not look at it. */ - if (path_dbtime == 0 || st->st_mtime > path_dbtime) { - state->processed_files++; - - status = notmuch_database_add_message (notmuch, next, &message); - switch (status) { - /* success */ - case NOTMUCH_STATUS_SUCCESS: - state->added_messages++; - tag_inbox_and_unread (message); - break; - /* Non-fatal issues (go on to next file) */ - case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: - /* Stay silent on this one. */ - break; - case NOTMUCH_STATUS_FILE_NOT_EMAIL: - fprintf (stderr, "Note: Ignoring non-mail file: %s\n", -next); - break; - /* Fatal issues. Don't process anymore. */ - case NOTMUCH_STATUS_READONLY_DATABASE: - case NOTMUCH_STATUS_XAPIAN_EXCEPTION: - case NOTMUCH_STATUS_OUT_OF_MEMORY: - fprintf (stderr, "Error: %s. Halting processing.\n", -notmuch_status_to_string (status)); - ret = status; - goto DONE; - default: - case NOTMUCH_STATUS_FILE_ERROR: - case NOTMUCH_STATUS_NULL_POINTER: - case NOTMUCH_STATUS_TAG_TOO_LONG: - case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: - case NOTMUCH_STATUS_LAST_STATUS: - INTERNAL_ERROR ("add_message returned unexpected value: %d", status); - goto DONE; - } - - if (message) { - notmuch_message_destroy (message); - message = NULL; - } - - if (do_add_files_print_progress) { - do_add_files_print_progress = 0; - add_files_print_progress (state); - } - } +
[notmuch] [PATCH] Mac OS X compatibility fixes
On Sun, 22 Nov 2009 12:31:53 +0800, Jjgod Jiang wrote: > On Sun, Nov 22, 2009 at 12:17 PM, Alexander Botero-Lowry > > The problem is that notmuch does not have a fully functional configure > process yet, Carl did mention Makefile.local, but it seems this file is > not generated by configure right now. (No config.h either.) We do now have Makefile.config being generated, (and we can move to config.h to avoid the overly-long command-line problem if necessary). > I will be happy to fix my patch if such facility (like > AC_CHECK_FUNCS([getline])) exists. Chris, do you want to tackle this one? ;-) A really easy hack would be to detect glibc, and if present, use all the existing code in notmuch. If not present, then use all the compatibility functions. This could be by building a notmuch-compat.c that defines functions like _notmuch_strndup() and then adding thins like: #define strndup _notmuch_strndup. That would allow our current configure script to stay quite simple. If people want more sophistication we could write functions in the configuration script for doing test compiles to find functions, etc. -Carl
[notmuch] Guide for new users?
On Sun, 22 Nov 2009 12:44:17 +0800, Jjgod Jiang wrote: > I think it will be nice if we can have a guide/tutorial like > documentation for new users. For myself, I have the following > questions (I am an alpine user previously, so some of the > questions are not related to notmuch directly): Hi Jiang, welcome to notmuch! There's definitely a lot more documentation we could use. I think one of the things I'd like to know is, where did you look when you wanted answers to these questions? That can help us know where the best places are to put some answers. As for getting started with notmuch itself, I've tried to make it fairly self-guided. (That is, if you just run "notmuch"[*] it should keep telling you what to do next.) I'd be very interested in getting feedback from people on how well this works. Did you run it that way? Were its suggestions helpful? [*] The assumption being that people will try to run the program before reading any documentation. > 1. What's the most efficient way to sync mails from my gmail > account to a local Maildir? I've tried offlineimap but it > keeps crashing python (!) on my system (python 2.6, Mac OS X > 10.6.2). One of the big tricks with switching to notmuch is that there's so much that notmuch doesn't do. If one is coming from a monolithic email program (such as evolution) or webmail (such as gmail) then notmuch only replaces a tiny piece of the mail program, (search and tagging). But the user also needs replacements for all of the other pieces of the mail program. Such as: * Receiving mail * Composing mail (with a nice address book) * Sending mail And likely other stuff I'm not thinking of right now. So those things can involve lots of different programs. For receiving it might be offlineimap, getmail, fetchmail, procmail, maildrop or some combination. For composing it could be emacs, vim, etc. And sending mail might involve msmtp, postfix, or exim4, etc. That's a long list of packages, and likely an overwhelming set of possibilities as well as a ton to learn for setting these up and configuring them. So I think you're right that we're going to want some guide suggesting best practicing for setting things like this up. > 2. How to add notmuch.el into my .emacsrc? We've at least added this much to INSTALL now. First do: sudo make install-emacs Then in your .emacs add: (require 'notmuch) And then you can run "M-x notmuch". > I know notmuch feels like a tool for geeks, but it will probably > lower the barrier if someone can provide such a guide in a > straightforward, step-by-step way. A "tool for geeks" means that it works well and efficiently, (without "fluff" or mis-features). It doesn't mean that it needs to be hard to learn, or require specialized knowledge in advance before using it. So yes, I totally agree that we need to document things like this better, and make it as easy to start using notmuch as possible. -Carl
[notmuch] Guide for new users?
On Sun, 22 Nov 2009 18:02:36 +0100, Jed Brown wrote: > Yes, however it will change flags which changes file names and currently > confuses notmuch. I synced [Gmail].All Mail with OfflineIMAP and am now > using Getmail to pull via POP. In the Gmail settings, activate POP > starting at the current time. I'll switch back to OfflineIMAP when > notmuch is happy with changing file names. Coming soon! I've been told the patch has been sent to the list already. > The following should save notmuch + Gmail users some time. Hey, that's a great document. We really need a nice wiki for notmuchmail.org already. (And when I say "wiki" I think I really mean something with email-based submission of some sort.) I suppose that with ikiwiki I could easily write a script to accept an email on stdin and make a git commit out of it. So then I could just pipe useful messages straight from my inbox to the wiki. I think that's what I'll do. (For now, I'll tag that message as notmuch-wiki so I will be able to easily find it later.) Another thing I'd really like would be a notmuch-based interface to our mailing list archives. Then I would tag the previous message as "howto", "gmail", "getmail", and "offlineimap". Anyway, thanks for sharing this! -Carl
[notmuch] [PATCH] Support multiple configuration files via $NOTMUCH_CONFIG
On Sat, 21 Nov 2009 23:18:26 -0600, Alec Berryman wrote: > If present, $NOTMUCH_CONFIG will be used as the configuration file > location. Hi Alec, welcome to notmuch! And thanks for this patch. I've pushed it now. I need this quite often when setting up a new database for testing a patch, for example. And I had an environment variable for the database path once upon a time, before adding a configuration file. But I lost that feature when adding the configuration file. So it's really nice to have this functionality back again. We should probably add support for "notmuch -f " as well. I've noted that idea in the TODO file now, (which just keeps growing somehow). -Carl
[notmuch] [PATCH] notmuch-new: Eliminate gcc warning caused by ino_cmp.
On Sun, 22 Nov 2009 13:32:36 +0100, Jan Janak wrote: > The function passed to scandir in the fourth argument takes two > const void* arguments. To eliminate the gcc warning about incompatible > types, we change ino_cmp to match this and then re-type the parameters > in the body of ino_cmp. Actually, on my system at least, (Linux with glibc 2.10.1), our current function matches the prototype. So applying your patch actually *introduces* a warning where there was no warning before. What a nuisance... Any ideas for a good fix, anyone? -Carl
[notmuch] [PATCH] makefile: Tell echo to interpret escape sequences.
On Sun, 22 Nov 2009 13:44:37 +0100, Jan Janak wrote: > The initial message that informs the user about the possibility to use > make V=1 contains a \n at the end, but echo wouldn't interpret that > properly without the -e command line option. Patch doesn't work for me. Before patch: 0:~/src/notmuch:(master)$ make Use "make V=1" to see the verbose compile lines. CCnotmuch-new.o CXX notmuch After patch: 0:~/src/notmuch:(master)$ make -e Use "make V=1" to see the verbose compile lines. CCdebugger.o -e CC gmime-filter-reply.o -e CC notmuch.o It's a shame that simple things like "echo" aren't easy to use portably. (And yes, I know that autoconf has a bunch of tests for echo, such as how to get the behavior of "echo -n", etc.) -Carl
[notmuch] [PATCH] notmuch-new: Eliminate gcc warning caused by ino_cmp.
On Mon, Nov 23, 2009 at 3:38 AM, Carl Worth wrote: > On Sun, 22 Nov 2009 13:32:36 +0100, Jan Janak wrote: >> The function passed to scandir in the fourth argument takes two >> const void* arguments. To eliminate the gcc warning about incompatible >> types, we change ino_cmp to match this and then re-type the parameters >> in the body of ino_cmp. > > Actually, on my system at least, (Linux with glibc 2.10.1), our current > function matches the prototype. So applying your patch actually > *introduces* a warning where there was no warning before. > > What a nuisance... > > Any ideas for a good fix, anyone? OK, I have an older version of glibc. If the original code works with glibc 2.10 then just ignore the patch. I think testing for a particular version of glibc is not worth the effort (it's just a warning anyway). -- Jan
[notmuch] [PATCH] makefile: Declare clean target as phony.
On Sun, 22 Nov 2009 13:55:35 +0100, Jan Janak wrote: > This ensures that make clean always proceeds, even if the user > accidentally creates a file named 'clean'. Also, it ignores errors in > rm and other commands. Now *this* patch worked fine for me. Thanks! I've pushed it now. -Carl
[notmuch] [PATCH] makefile: Tell echo to interpret escape sequences.
On Mon, Nov 23, 2009 at 3:41 AM, Carl Worth wrote: > On Sun, 22 Nov 2009 13:44:37 +0100, Jan Janak wrote: >> The initial message that informs the user about the possibility to use >> make V=1 contains a \n at the end, but echo wouldn't interpret that >> properly without the -e command line option. > > Patch doesn't work for me. > > Before patch: > > ? ? ? ?0:~/src/notmuch:(master)$ make > ? ? ? ?Use "make V=1" to see the verbose compile lines. > ? ? ? ? ?CC ? ?notmuch-new.o > ? ? ? ? ?CXX ? notmuch > > After patch: > > ? ? ? ?0:~/src/notmuch:(master)$ make > ? ? ? ?-e Use "make V=1" to see the verbose compile lines. > ? ? ? ? ?CC ? ?debugger.o > ? ? ? ?-e ? CC gmime-filter-reply.o > ? ? ? ?-e ? CC notmuch.o > > It's a shame that simple things like "echo" aren't easy to use portably. > (And yes, I know that autoconf has a bunch of tests for echo, such as > how to get the behavior of "echo -n", etc.) It seems your echo interprets escape sequences by default. When I run make, the first line of output looks like this: Use "make V=1" to see the verbose compile lines.\n CC debugger.o CCgmime-filter-reply.o CCnotmuch.o This is on Debian Lenny. Anyway, this one is not important either. -- Jan
[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags
On Sun, 22 Nov 2009 15:32:13 -0800, Keith Packard wrote: > That's a fine plan. It 'shouldn't' be too hard to implement either. Noted in TODO for future reference. > Btw, I'm thinking that it might be useful to create some 'global' > notmuch keybindings and then create per-view bindings that also expose > the global bindings. That way, things like 'm' to create a new mail > would work consistently in each view. Note that this idea is > inconsistent with the following though... That's an excellent idea. And it's consistent with what I want 'a' to do, (and I do think it's important to have these commands consistent across the views). I think it's natural too. See below... > I was trying to make the 'normal' action easier; for me, if I'm looking > at a message, then the normal action is to mark it read and archived, > but when I'm looking only at the subject line in the search window, the > normal action is just to mark it archived (having not actually read the > message). I agree that "normal" should be easier too. So I just need to win you over to my notion of "normal", (and teach you of the ways of the magic space bar). The most normal thing (for me) to do *when at the end of a thread* is to mark it read, archive it, and then advance to the next message. And that's exactly what space bar does. If you're not at the end of a thread, then you can archive it, (that's what 'a' is for), but it shouldn't be marked read, (because otherwise that would be "cheating").[*] And if you want to cheat willingly, (notmuch, please consider these messages read even though you've never presented them to me), then that should require an extra-explicit action. So that's the shift key. [*] We should perhaps fix 'a' to remove the "unread" tag from any messages that _are_ wholly visible in the current window. It's really only when an entire thread fits this one, and I *did* read it, that I end up reaching for the 'A' binding. So does that make sense? The question of whether you next want to see the next message, or you would rather return to the search view, is a trickier one. I'd suggest that there's no harm in seeing the next message after archiving the current message, from which you can immediately return to the search view with 'q' (or 'x' currently, but not with your patch). That does mean that "archive and return to search" does require two keys instead of one. Hmm... if we fix 'a' to correctly remove "unread" from wholly presented messages, then I wouldn't need the current 'A' keybinding at all. That is, notmuch would be automatically managing "unread" tags in a fairly consistent way, and we wouldn't be giving UI for the "cheating", (which should be fine---I can't see a good reason for cheating here). If we did that, then we could make 'a' do archive-go-to-next-message and 'A' do archive-return-to-search-view. What would you think about that? -Carl Date: Mon, 23 Nov 2009 04:02:59 +0100 Message-ID: <871vjqgcyk.fsf at yoom.home.cworth.org>
[notmuch] [PATCH] Add SCons build files.
On Sun, 22 Nov 2009 07:47:10 -0600, "Jeffrey C. Ollie" wrote: > The SCons build files included here *should* do everything that the > current Makefiles do, plus a little bit of configuration checking. To > build/install: Hi Jeffrey, Thanks for your effort to code all this up. But I'm afraid I really don't want to switch away from just using (GNU) make for the actual compilation. I don't know anything about scons, but if you can use it to write a python script that just does the configuration step, (outputting a Makefile.config say), then that might be very interesting. Some people have recently told me that python would be a much more sane language for doing configuration in than shell. I don't know if they're right or not, but I'm (somewhat) willing to have multiple implementations of the configure script (since there's always the option to just skip it and configure Makefile.config manually). But I'm definitely not willing to have multiple build systems. > Yes, I'm sure that make is widely available, but as notmuch gets used > on a wider variety of systems some sort of configuration system will > become necessary. If I can prevent another project from going down > the autoconf/automake path I'll be happy. I started creating CMake > build files but I don't know CMake well enough to come up with a > working build. I'm totally glad to try to avoid autoconf/automake. I know for sure that I never want to use libtool again, (I've learned that the hard way). I don't have as much prejudice against automake, but I've heard a rumor that it's hard to make it *not* use libtool. Meanwhile, the only advantage I know for automake is that once it's setup, adding a new file to compile is as simple as adding one file to a list in the Makefile.am. We've already got notmuch as easy as that with just adding a file to a list in Makefile.local. So then all that's left is a configuration system. The notion of how the final "configure" script from autoconf works seems just fine to me, but I'm not sure the implementation of autoconf itself is sound. I've been maintaining a project for years (cairo) where the m4-complexity in configure.ac has far outgrown my ability to understand it. And I'm extremely uncomfortable with a build system I can't understand. Meanwhile, cairo *still* has a shell script needed just to bootstrap the autconf/automake/libtool house of cards, and that shell script alone is 194 lines. So I'd very much like to continue exploring what we can do with our own configuration system, (in whatever language/language(s) make sense). In the meantime, I'm happy that I can just checkout and build notmuch on a Linux system with no configure step at all. I also like that the build-system doesn't trigger constant re-runs of configure all the time. I've spent too many days of my life watching autoconf output scroll by, and I'd really like to avoid going down that road. So yes, Jeffrey, if avoiding autoconf is the motivation, then I'm right there with you. But I'm not convinced that throwing out GNU make is the right thing to do as well. Thanks for listening, -Carl
[notmuch] [PATCH] fix compiler warnings
On Sun, 22 Nov 2009 17:11:03 +0200, Dirk-Jan C. Binnema wrote: > > (hopefully this is the correct way to send patches...) Looks just fine, and welcome to notmuch! > With these minor changes, notmuch compiles warning-free with gcc 4.4.1 Could you resend these as separate patches, each patch fixing a single type of warning? That would make it more clear what the code is doing. > -write(2, msg, sizeof(msg)-1); > +if (write(2, msg, sizeof(msg)-1) < 0) { > + /* ignore...*/ > +} I don't like the gratuitous conditional here. It clutters the code and make is less clear. If we're just trying to squelch a warning about an unused return value from a function, then I think I'd rather see: ssize_t ignored; ignored = write (2, msg, sizeof (msg) - 1); What do you think? -Carl
[notmuch] 25 minutes load time with emacs -f notmuch
On Sun, 22 Nov 2009 10:15:39 -0500, Brett Viren wrote: > On Sun, Nov 22, 2009 at 3:36 AM, Mike Hommey > wrote: > But, here is one that looks I/O bound: > > notmuch tag -unread tag:inbox > > I have my home directory on an encfs volume and I see it and notmuch > competing for CPU when viewing "top". Yes. The "notmuch tag" command currently does much more IO than it really should. This is Xapian bug 250. Please see: id:874oon4pgv.fsf at yoom.home.cworth.org for some details and thoughts on the bug from me and some pointers on how one could go about fixing it. -Carl
[notmuch] [PATCH] fix notmuch-new bug when database path ends with a trailing /
On Sun, 22 Nov 2009 11:19:31 -0500, Bart Trojanowski wrote: > The actual bug was in the filename normalization for storage in the > database. The database.path was removed from the full filename, but if > the database.path from the config file contained a trailing /, the > relative file name would retain an extra leading /... which made it look > like an absolute path after it was read out from the DB. Thanks for the fix, Bart! I've pushed this out now. -Carl
[notmuch] [RFC PATCH -V2] notmuch: Add support for multiple maildirs
On Sun, 22 Nov 2009 23:58:46 +0530, "Aneesh Kumar K.V" wrote: > This patch separate database path and maildir paths. > It also adds support for multiple maildir paths which > is represented by comma separated values. I have a running joke with my good friend Behdad that we should add a git-hook to refuse any commit with the word "also" in the commit message. It's often a sign that the commit is actually doing two independent things, and that those two independent things should be split into separate commits. I think that's the case here. > You need to have in ~/.notmuch-config > [maildirs] > path=path1,path2 Documentation in the commit message doesn't count. We need this documentation to be inserted into the configuration file as a comment, like with the other values. > + dirs = g_key_file_get_string (config->key_file, > + "maildirs", "path", NULL); > + if (dirs) { > + size = sizeof(struct count_ele) + strlen(dirs) + 1; > + /* comma separated paths */ > + maildirs = (struct count_ele *)malloc(size); There's a g_key_file_get_string_list function that will do all the splitting of a multiple-valued configuration entry into multiple strings. I suggest using that here instead of doing open-coded parsing. > -prompt ("Top-level directory of your email archive [%s]: ", > +prompt ("Directory for notmuch database [%s]: ", Is there really a reason to prompt for this here, rather than just using a default value (and letting the user know what it is?). One thing I'm worried about is the user thinking they can run "notmuch setup", change this value, and expect things to work, (which of course, they won't). I'd be happier if the user understood that the database is relocatable and they can just "mv" things around as they want to. Of course, for that, then we'd actually need to *make* the database relocatable. One thing that we get right now with the .notmuch directory _inside_ the mail directory is that everything is relocatable. If you just pull it out, like you do here, then suddenly the database will be full of absolute paths to mail files, and things will break if the top-level mail-directory is moved. And that's a regression compared to the current case. > +prompt ("Comma separated maildirs [%s]: ", cmaildirs); If we are going to support multiple directories for mail here, then we should prompt separately for each (like we are doing for the email addresses already). Also, I'd prefer something like "Top-level directory of email archive" like we had before. I certainly don't want to give the user the impression that they need to type in a path to each individual maildir that they have. Finally, (and maybe I should have started with this), what's the actual use case here? Is it difficult to just arrange all mail to be under one top-level directory, (perhaps just using symlinks even). -Carl
[notmuch] [PATCH] New function notmuch-search-operate-all: operate on all messages in the current query.
On Sun, 22 Nov 2009 21:12:16 +0100, Jed Brown wrote: > It is often convenient to change tags on several messages at once. This > function applies any number of tag whitespace-delimited tag > modifications to all messages matching the current query. > > I have bound this to `*'. Very nice, Jed! I've been wanting this feature for a while, and I think you just improved on my idea in at least two ways. First I was imagining that the '*' would be a prefix command, but I like it just prompting for the '+' or '-' as part of the argument. That's no more typing and allows for doing multiple tags at once. Second, I like that you just used the search string again, (as opposed to just walking through the buffer looking at thread IDs). That seems elegant. On second thought, however, using the search string is problematic for at least two reasons: First, this creates a race condition in that the user will rightly expect to only be adding/removing tags from the visible results. But if new mail has been incorporated between creating the current view and running '*' then threads could be tagged that were never seen and that could be problematic. Second, since we're in the search view which shows threads, we should really be operating on threads. But this tag command won't work like the '+' and '-' commands in this buffer. Those commands will add/remove a tag to/from every message in the thread[*]. The new '*' command, however will only be changing tags on messages that match the query. So I think we should fix both of these issues by looping over each line of the buffer and calling (notmuch-search-add-tag) or (notmuch-search-remove-tag). What do you think? -Carl [*] These existing '+' and '-' operations (as well as 'a') that act on the entire thread also have a race condition. They are potentially modifying more messages than the original search matched. This is often harmless, (you aren't even *seeing* the messages so how can you complain if more get modified than were there when you did the search.). But it can actually be fatal: Imagine I sent a message to the list, and then in the search view I see that message appear and it has [1/1] indicating it's the only message in the thread. I might archive this "knowing" I've read the message already, but this could actually archive a reply as well that arrived between when I did the search and when I archived. So that's a bug that we really should fix. [And noted that archiving an entire thread from the notmuch-show-mode does not have this bug since it acts only on the explicit messages that are presented.] One option to fix this would be for "notmuch search" to list all the message IDs that matched in place of the thread ID (for notmuch-search-mode to hide away like it does with the thread ID currently). But that seems like it might get problematic with some hugely long threads. Anyway, I'm interested in ideas for what we could do here. Oh, here's one: We could add something like "notmuch tag --expecting= 1/23 " that would not do the tag unless the search string matched 1 message out of 23 total messages in the thread. Then we could give a warning to the user. That works for the single-thread case, but the warning would be harder for the user to deal with in the '*' case. Or maybe not---the emacs function could just stop on the first line with the error and then the user would see what's going on. And we could take a prefix argument to ignore such errors. Any other thoughts on this?
[notmuch] How to index /var/spool/mail with notmuch
On Sun, 22 Nov 2009 21:24:47 +0100, Tassilo Horn wrote: > But I get some permission problems when trying to index /var/spool/mail. > I was able to create a .notmuch/ directory in there with permissions set > to 700 for my user. All mail files are readable for my user. > > Unfortunately, there are some dovecot internal files, which should > neither be indexed by notmuch, and which have 600 permissions for the > mail user. And that's where notmuch errors and stops indexing. :-( Hi Tassilo, welcome to notmuch! I'm glad you found a workaround for this problem, (thanks Jed!). But perhaps these errors should be made into warnings instead? Any thoughts on that anyone? > All "real" mail files are named "u.", so it would be cool if I > could provide a pattern to notmuch matching all files I'd like to index. > And maybe the other way round (a blacklist pattern) would be useful, > too. I've been planning on having a blacklist pattern for a while. Originally, the only difficulty in implementing it was that we had nowhere to store configuration information. But we have a configuration file now, so this would be a pretty easy thing to implement. It's not as obvious that a whitelist pattern would be as widely useful, but it would be possible too. -Carl
[notmuch] [PATCH] Add install target for desktop files.
On Sun, 22 Nov 2009 15:17:11 -0600, "Jeffrey C. Ollie" wrote: > Add an install target that uses desktop-file-install to install the > desktop file in the appropriate location. The location of the install > can be modified by changing the desktop_dir variable. Hi Jeffrey, I suppose if we're going to have a .desktop file it only makes sense to install it. A couple of questions: > +install-desktop: > + install -d $(DESTDIR)$(desktop_dir) > + desktop-file-install --mode 0644 --dir $(DESTDIR)$(desktop_dir) > notmuch.desktop What does desktop-file-install do for us here? Anything that we couldn't do with just "install"? I'm just wanting to be careful that we don't break "make install" for people who may not even want this file. If we really do need to install it with desktop-file-install, we could do a configure check for that program, of course. Thanks, -Carl
[notmuch] [RFC] Precedence of OR and AND
On Sun, 22 Nov 2009 22:43:30 +0100, Jed Brown wrote: > On Sun, 22 Nov 2009 16:36:49 -0500, Bart Trojanowski > wrote: > Absolutely, and I have this applied locally to notmuch.el, Patch please? >but I didn't > fix notmuch-search-filter-by-tag because that would really need to parse > the expression. I don't see the difference here. Any time we append to the search string, we should be doing so with parentheses. > I'm just asking if anyone else thinks binding OR > tighter than AND would be desirable. Right now, Xapian is doing all of our query parsing. So we'd have to take things up there to get anything changed for now. In the future we might be forced into writing our own query parser to get all the functionality we want. -Carl
[notmuch] Catching up unread messages
On Sun, 22 Nov 2009 22:48:52 +0100, Tassilo Horn wrote: > I got notmuch running, and it's absolutely incredible. It's so damn > fast and the results are very good. So thanks a lot for creating this > nice piece of software. :-) Fantastic, Tassilo. I'm glad you got things working and are happy with the results. And you're quite welcome. I'm just glad I'm able to share something that has been really useful for me. > Ok, so new the question: I indexed all my 63.000 mails, and because it > was a first-time indexing, all my mail now has the tags inbox and > unread. Of course, I don't want to SPC through all threads (using the > great emacs interface) to remove the unread status. So is there some > catchup command, which marks all messages in the buffer as read? If you were to look at the notmuch/TODO file right now, you would see as the first lines: Fix the things that are causing the most pain to new users -- 1. A new import is tagging all messages as "inbox" -- total pain So yes, I understand that this is not useful behavior! Also, the pain is amplified because the command to *remove* these tags is currently very slow. So there's some work we need to do before the initial experience with notmuch is really pleasant for a lot of people. > BTW, what's the intention of the inbox tag? When I've read a thread, > both inbox as well as unread disappear, so I don't get the difference > between them. If you get half-way through reading a thread, and then exit, then when you come back to that thread, notmuch will start you out at the first unread message in the thread, (and all the read messages will be collapsed). Also I often end up archiving entire threads without reading them, (often for mailing lists that I don't read closely, but just skim the subject lines once a day or so). For cases like this, I think it's useful to be able to say things like: I almost never read this list in its entirety, but I want to find that message I actually did read recently: notmuch search tag:lkml and tag:read Another thing that I think is a little bit useful is if someone points me to a specific message, it's nice to be able to see "unread" and say "Oh, yeah, I don't think I ever read that at all." So that's the idea anyway, (and thanks to sup for showing us the way here). -Carl
[notmuch] [PATCH 3/3] change config file location to be ~/.notmuch/config
On Sun, 22 Nov 2009 18:14:20 -0500, Jameson Graef Rollins wrote: > I think Carl said he wanted to keep the ability to specify exactly > where the database is stored, so if we could move away from something > that makes any implicit assumptions about relative paths between the > database and the maildir, then all should be ok. Well, I chose the relative-path assumptions intentionally. The idea is that if I move my mail from ~/Mail to ~/mail then the .notmuch directory moves with it and everything continues to work just fine. Compare the way .git works and the database stays with the source files compared to the way cvs works, (where I always seemed to end up with source files disconnected from the database). So I might need more convincing to move the database away from the mail. -Carl
[notmuch] [PATCH] Support for printing file paths in new command
On Mon, 23 Nov 2009 01:53:39 +0100, Adrian Perez de Castro wrote: > IMHO it would be nice to have the messages-per-second information as > well in verbose mode before making it the default. I think I could cook > up a patch for that, but printing messages-per-second would mean calling > gettimeofday() for each processed file. Do you think that will be > acceptable from a performance POV? (Of course using silent mode would > still only call it once per second). Or how about using the existing timer to cause a rate to be printed between the message output once per second? -Carl
[notmuch] [PATCH] ANSI escapes in "new" only when output is a tty
On Mon, 23 Nov 2009 01:54:35 +0100, Adrian Perez wrote: > When running "notmuch new --verbose", ANSI escapes are used. This may not be > desirable when the output of the command is *not* being sent to a terminal > (e.g. when piping output into another command). In that case each file > processed is printed in a new line and ANSI escapes are not used at > all. I've pushed this now. And I've noticed two things with it: 1. The filenames are often quite long, and if longer than my terminal width, then I get one line per output rather than one line continually erased and reprinted. Any good idea about how to fix that without going too crazy? 2. On any run after the first, the output says "1/0", "2/0", etc. So we should fix that to either not print the "/0" when total_messages is 0 *or* we can just make "notmuch new" unconditionally count the number of files to be processed, (which I've been thinking I wanted to do anyway). I'm trying to eliminate any remaining differences between "notmuch new" on an initial run and "notmuch new" run later. An important reason to eliminate these differences is that we want to support the user interrupting the initial database build and then starting it up again without losing anything. Besides the file counting, (which would only make such a user lose the countdown timer on the subsequent runs), the only other thing we have different about the first run is that it doesn't ignore read-only directories. And that one's a problem because it means that if someone (like me) that has a bunch of read-only directories does the following: notmuch dump notmuch.dump rm -rf ~/mail/notmuch notmuch new # then interrupt this with control-C notmuch new # oops! This missed most of my mail notmuch restore notmuch.dump Things go badly wrong here as any mail in read-only directories that didn't get picked up in the first "notmuch new" run will forever more be ignored by notmuch new. So that's totally broken and we should come up with a way to fix it. -Carl
[notmuch] [PATCH -v3] notmuch.el: Add face support to search and show mode
This add two faces, notmuch-show-subject-face and notmuch-tag-face. The first face is used to show the subject line in the notmuch-show-mode and the second one to show tags in the notmuch-search-mode. We can selectively highlight each tag by setting notmuch-tag-face-alist as below (defface notmuch-tag-unread-face 'class color) (background light)) (:foreground "goldenrod" :bold t)) (((class color) (background dark)) (:foreground "goldenrod" :bold t))) "Notmuch search mode face used to highligh tags.") (defface notmuch-tag-inbox-face 'class color) (background light)) (:foreground "red" :bold t)) (((class color) (background dark)) (:foreground "red" :bold t))) "Notmuch search mode face used to highligh tags.") (setq notmuch-tag-face-alist '(("unread" . 'notmuch-tag-unread-face) ("inbox" . 'notmuch-tag-inbox-face))) (require 'notmuch) Signed-off-by: Aneesh Kumar K.V --- notmuch.el | 40 ++-- 1 files changed, 38 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 1f24461..2aa6d5a 100644 --- a/notmuch.el +++ b/notmuch.el @@ -686,6 +686,18 @@ which this thread was originally shown." (force-window-update) (redisplay t)) +(defface notmuch-show-subject-face + 'class color) (background light)) (:foreground "yellow" :bold t)) +(((class color) (background dark)) (:foreground "yellow" :bold t))) + "Notmuch show mode face used to highligh subject line." + :group 'notmuch) + +(defvar notmuch-show-font-lock-keywords + (list ;; header in font-lock-type-face + (list "\\(Subject:.*$\\)" +'(1 'notmuch-show-subject-face))) + "Additonal expression to hightlight in notmuch-show-mode") + ;;;###autoload (defun notmuch-show-mode () "Major mode for viewing a thread with notmuch. @@ -726,7 +738,9 @@ view, (remove the \"inbox\" tag from each), with (use-local-map notmuch-show-mode-map) (setq major-mode 'notmuch-show-mode mode-name "notmuch-show") - (setq buffer-read-only t)) + (setq buffer-read-only t) + (set (make-local-variable 'font-lock-defaults) + '(notmuch-show-font-lock-keywords t))) ;;;###autoload @@ -855,6 +869,17 @@ thread from that buffer can be show when done with this one)." (goto-char (point-max)) (forward-line -1)) +(defface notmuch-tag-face + 'class color) (background light)) (:foreground "goldenrod" :bold t)) +(((class color) (background dark)) (:foreground "goldenrod" :bold t))) + "Notmuch search mode face used to highligh tags." + :group 'notmuch) + +(defvar notmuch-tag-face-alist nil + "List containing the tag list that need to be highlighed") + +(defvar notmuch-search-font-lock-keywords nil) + ;;;###autoload (defun notmuch-search-mode () "Major mode for searching mail with notmuch. @@ -885,7 +910,18 @@ global search. (setq truncate-lines t) (setq major-mode 'notmuch-search-mode mode-name "notmuch-search") - (setq buffer-read-only t)) + (setq buffer-read-only t) + (if (not notmuch-tag-face-alist) + (add-to-list 'notmuch-search-font-lock-keywords (list + "\\(([^)]*)$\\)" '(1 'notmuch-tag-face))) +(progn + (setq notmuch-search-tags (mapcar 'car notmuch-tag-face-alist)) + (loop for notmuch-search-tag in notmuch-search-tags +do (add-to-list 'notmuch-search-font-lock-keywords (list + (concat "\\(" notmuch-search-tag "\\)") + `(1 ,(cdr (assoc notmuch-search-tag notmuch-tag-face-alist + (set (make-local-variable 'font-lock-defaults) + '(notmuch-search-font-lock-keywords t))) (defun notmuch-search-find-thread-id () (save-excursion -- 1.6.5.2.74.g610f9
[notmuch] [RFC PATCH -V2] notmuch: Add support for multiple maildirs
On Mon, Nov 23, 2009 at 04:51:34AM +0100, Carl Worth wrote: > Finally, (and maybe I should have started with this), what's the actual > use case here? Is it difficult to just arrange all mail to be under one > top-level directory, (perhaps just using symlinks even). > Ok i switched to using a separate directory for notmuch and symlink the interested folders into that. So you can ignore the patch -aneesh
[notmuch] notmuch 'index' mode.
On Fri, 20 Nov 2009 23:35:29 -0800, Keith Packard wrote: > I posted a patch adding an 'index' mode to notmuch and though I'd > explain my idea. Most mail systems provide a 'folder view' mode which > displays the set of folders and a count of messages in each folder. I > used this myself as the first sort of which messages I want to read. I've just pushed this set of patches out now. I like it quite a bit. Here are some thoughts: * The mode documentation really needs to walk the user through how to setup a custom set of folders. * It's not opening my "to-me" folder for some reason. (I thought it was the '-' at first, but "xorg-board" is working fine). I can debug this later. * The presentation is impressively spartan[*]. :-) If we spruce this up a bit, I think we'll want to make this the default view of "M-x notmuch". Oh, and instead of just documenting how to set a variable in .emacs we should just provide commands to add/remove folders. > One missing piece here is that the searches don't have a > total/unread count. Because the 'notmuch count' command is so fast > (notmuch count the returns 532891 on my machine, and takes 0.240 > seconds), we really could count the number of messages matching a single > tag and then *also* count the number of messages matching that tag and > the inbox tag. I think the number of threads matching the search is the only interesting number actually. Otherwise, you just end up printing a bunch of big numbers that the user doesn't need for anything. > Another missing piece is that these should be shared with the > notmuch-poll script, probably via the .notmuch-config file. I do like > that I can have some entries here that aren't in my notmuch-poll script. Yes, once we add configuration for automated tagging, we'll want to figure out how to include those here. I'm not sure if they should just be an initial default that the user tweaks, or if any configured rules from that file should always be presented until the user explicitly asks for one to be ignored (think about a "spam" tag). So that might take some experimentation. You're definitely right that we want to support searches other than simply the tag names in the configuration file. For example, here's the search I'm currently using for the "notmuch" folder (so I can process outstanding patches in order): tag:notmuch and (tag:inbox or tag:todo) Though, really, I probably wouldn't mind using a search string like that for any of my automated tags. It's equivalent to what you were doing if there are no "todo" tags on messages with the tag of interest, and then as soon as there are any "todo" tags on any of those messages, then I probably do want them in that folder. So maybe the user configures a search template to use for each automatic tag or so? > It might be nice to make this hierarchical as I used to do with > evolution's vfolder stuff -- an 'intel' folder with an 'intel/unread' > sub-folder. That would be done with simple conjunctions of tags, but > providing some structure on the screen might be nice. > > I'm also wondering if we should elide, or at least change the appearance, > of lines which match zero messages. Two nice ideas. > I'd also like to be able to get the system to display my mail in three > panes -- one with the index, one with the current search and the last > with the current thread. Getting those laid out on the screen correctly > and letting you get them back to that layout easily would make notmuch > look a lot more like other email clients, a form I've found fairly > functional as I do not generally read mail in a linear fashion. Yes. Emacs has pretty good support for saving and restoring an entire window configuration, so we should be able to make this work. And by the way, lest you be misled by the "magic space bar", I don't read my mail very linearly either. I always filter by at least one tag first and I want to prioritize which one. The folder mode is great for this. It's only when I get my search results down below a particular threshold that I decide I want to read everything linearly. (And if I can't get a particular folder down that small, then I'll do selective reading (with 'x', yes, I think we're agreeing on that now), and then archive away the lot.) Anyway, thanks for the great addition to notmuch. -Carl [*] A nice thing about this is it give us plenty of room to have a paragraph or two explaining how notmuch works, what the user can expect, what keys to use, etc.
[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values
From: Dirk-Jan C. Binnema Date: Mon, 23 Nov 2009 08:03:35 +0200 --- notmuch-new.c |4 +++- notmuch-tag.c |4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/notmuch-new.c b/notmuch-new.c index a2b30bd..3d04efa 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -35,8 +35,10 @@ static volatile sig_atomic_t interrupted; static void handle_sigint (unused (int sig)) { +ssize_t ignored; static char msg[] = "Stopping... \n"; -write(2, msg, sizeof(msg)-1); + +ignored = write(2, msg, sizeof(msg)-1); interrupted = 1; } diff --git a/notmuch-tag.c b/notmuch-tag.c index e2311f6..ec98c3b 100644 --- a/notmuch-tag.c +++ b/notmuch-tag.c @@ -25,8 +25,10 @@ static volatile sig_atomic_t interrupted; static void handle_sigint (unused (int sig)) { +ssize_t ignored; + static char msg[] = "Stopping... \n"; -write(2, msg, sizeof(msg)-1); +ignored = write(2, msg, sizeof(msg)-1); interrupted = 1; } -- 1.6.3.3
[notmuch] [PATCH] Add SCons build files.
On Sun, 22 Nov 2009 22:36:30 -0600, Jeffrey Ollie wrote: > Well, to me, part of the appeal of SCons is that it doesn't generate > Makefiles.This article is a little old, but the first three > sections are a pretty good rundown on the limitations of Make. > > http://www.scons.org/wiki/FromMakeToScons Not very convincing to me at least. Half of it is limitations of various make implementations, (notmuch is definitely not trying to be portable across those---it uses GNU make). The other half is about problems in how make is often used, (like slow recursive make runs, or incomplete dependencies---but we've got a nice non-recursive make setup in notmuch and good dependency generation). It is true that make is doing timestamp-based checks rather than content-based, but things like this are things that people are quite familiar in deailing with. > If you really want a tool that generates Makefiles, take a look at > CMake. No I don't want a tool to generate Makefiles. I want to write the Makefiles, (which I've done). I'm willing to have a tool to create the configuration, (really just some variables accessible at compile-time). Right now we're storing these in a Makefile snippet named "Makefile.config" but we could just as easily be putting them in "config.h". > I think that having multiple different configuration systems would be > pretty awful, especially if people make changes to their favourite > configuration system and hope that someone else fixes the others. It's early times. I'm willing to entertain different ideas and have people propose different means of doing the configure step. Long-term we'll likely only have one supported thing. > It would seem to me that we would be re-inventing a lot of the work > already done by other people. But there's really so little to invent here. It's just not that hard to do the kinds of configuration that notmuch needs. So far we've got a few pkg-config checks and that gets us a long ways. Beyond that, the only portability improvements requested so far will require only the following from configure: * Find which of the compiler warning flags we want are available. * Find whether we have some particular library functions are available. And for these steps, all we have to do is to *compile* some test programs. And compiling programs is something our build system knows how to do already (since that's all it does). So I'm just not seeing that we'll spend much time reinventing anything. -Carl
[notmuch] [PATCH 2/2] * avoid gcc 4.4.1 compiler warning due to ignored 'fflush' return value
--- notmuch-setup.c | 13 +++-- 1 files changed, 7 insertions(+), 6 deletions(-) diff --git a/notmuch-setup.c b/notmuch-setup.c index d06fbf8..c50f812 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -100,12 +100,13 @@ notmuch_setup_command (unused (void *ctx), unsigned int i; int is_new; -#define prompt(format, ...)\ -do { \ - printf (format, ##__VA_ARGS__); \ - fflush (stdout);\ - getline (&response, &response_size, stdin); \ - chomp_newline (response); \ +#define prompt(format, ...)\ +do { \ + int ignored;\ + printf (format, ##__VA_ARGS__); \ + fflush (stdout);\ + ignored = getline (&response, &response_size, stdin); \ + chomp_newline (response); \ } while (0) config = notmuch_config_open (ctx, NULL, &is_new); -- 1.6.3.3
[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags
On Sun, 22 Nov 2009 19:52:00 -0800, Keith Packard wrote: > I'd take 'x' for 'return to search view; otherwise you're going to wear > out my pinky reaching for the shift key. That leaves us with three > commands: > > 'a': advance to next message, archiving current thread, marking read > messages. ('A' forces all messages in thread to be marked as read) > > 'x': exit to search view, archiving current thread, marking read > messages. ('X' forces all messages in thread to be marked as read) > > 'q': quit back to search view, leaving thread tags unmodified. OK. You win. That looks pretty good to me. > There's a slightly weird asymmetry here -- there's no way to advance to > the next thread and not mark messages. Well, there's "q, n, RET" at least. ;-) -Carl
[notmuch] [PATCH] makefile: Tell echo to interpret escape sequences.
On Mon, Nov 23, 2009 at 3:41 AM, Carl Worth wrote: > It's a shame that simple things like "echo" aren't easy to use portably. > (And yes, I know that autoconf has a bunch of tests for echo, such as > how to get the behavior of "echo -n", etc.) I think the standard workaround is to use "printf" instead. -- Karl Wiberg, kha at treskal.com subrabbit.wordpress.com www.treskal.com/kalle
[notmuch] interesting project!
Hi Carl, > "Carl" == Carl Worth writes: Carl> On Sun, 22 Nov 2009 14:23:10 +0200, Dirk-Jan C. Binnema Carl> wrote: >> A small question: it seems that notmuch is avoiding the use of GLib directly >> (of course, it depend on it anyway through GMime); is this because of >> OOM-handling? It'd be nice if GLib could be used, it would make some things >> quite a bit easier. Carl> It's true that I don't like the OOM handling in glib. I also think that Carl> glib tries to be too many different things at the same time. And Carl> finally, having some talloc-friendly data structures (like a hash-table) Carl> would be really nice. Well, the counter point to the OOM-problems is that is that in many programs, the 'malloc returns NULL'-case is often not very well tested (because it's rather hard to test), and that at least on Linux, it's unlikely that malloc ever does return NULL. Lennart Poettering wrote this up in some more detail[1]. Of course, the requirements for notmuch may be a bit different and I definitely don't want to suggest any radical change here after only finding out about notmuch a few days ago :) (BTW, there is a hashtable implementation in libc, (hcreate(3) etc.). Is that one not sufficiently 'talloc-friendly'? It's not very user-friendly, but that's another matter) Carl> In the meantime, as you say, we're already linking with glib because of Carl> GMime, so there's really no reason not to call functions that are there Carl> and that do what we want. What kinds of things were you thinking of that Carl> would be easier with glib? I could imagine the string functions could replace the ones in talloc. There are many more string functions, e.g., for handling file names / paths, which are quite useful. Then there are wrappers for gcc'isms (G_UNLIKELY etc.) that would make the ones in notmuch unneeded, and a lot of compatibility things like G_DIR_SEPARATOR. And the datastructures (GSlice/GList/GHashtable) are nice. The UTF8 functionality might come in handy. Anyway, I was just curious, people have survived without GLib before, and if you dislike the OOM-strategy, it's a bit of a no-no of course. Best wishes, Dirk. [1] http://article.gmane.org/gmane.comp.audio.jackit/19998 -- Dirk-Jan C. Binnema Helsinki, Finland e:djcb at djcbsoftware.nl w:www.djcbsoftware.nl pgp: D09C E664 897D 7D39 5047 A178 E96A C7A1 017D DA3C
[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values
On Mon, Nov 23, 2009 at 7:20 AM, Dirk-Jan C. Binnema wrote: > + ? ?ssize_t ignored; > ? ? static char msg[] = "Stopping... ? ? ? ? \n"; > - ? ?write(2, msg, sizeof(msg)-1); > + > + ? ?ignored = write(2, msg, sizeof(msg)-1); > ? ? interrupted = 1; > ?} Didn't the "(void)" suggestion work? -- Karl Wiberg, kha at treskal.com subrabbit.wordpress.com www.treskal.com/kalle
[notmuch] How to index /var/spool/mail with notmuch
Carl Worth writes: Hi Carl, >> Unfortunately, there are some dovecot internal files, which should >> neither be indexed by notmuch, and which have 600 permissions for the >> mail user. And that's where notmuch errors and stops indexing. :-( > > Hi Tassilo, welcome to notmuch! > > I'm glad you found a workaround for this problem, (thanks Jed!). Trying out notmuch already cashed out. ;-) > But perhaps these errors should be made into warnings instead? Any > thoughts on that anyone? I think so. For other dovecot internal index files it already says something like "Ignoring non-mail file foobar.idx" and simply skips that file. I think that's the right thing to do for files where it has no read permissions for, too. >> All "real" mail files are named "u.", so it would be cool if >> I could provide a pattern to notmuch matching all files I'd like to >> index. And maybe the other way round (a blacklist pattern) would be >> useful, too. > > I've been planning on having a blacklist pattern for a while. > Originally, the only difficulty in implementing it was that we had > nowhere to store configuration information. But we have a > configuration file now, so this would be a pretty easy thing to > implement. > > It's not as obvious that a whitelist pattern would be as widely > useful, but it would be possible too. Well, for dovecot users using the dbox format, a whitelist pattern would be much simpler because of the coherent mail file naming. But I could live with a blacklist pattern, too. Bye, Tassilo
[notmuch] notsomuch, a dummy curses ui
Hi notmuch community, As I'm not an emacs user, I started to play with the code to see what are the power of notmuch. I create a simple ncurses ui: http://gitorious.org/notsomuch Up to now it don't do much, just display searches and threads. It don't even display the content of the emails. I guess I'll be playing with it for some weeks, but not sure jet if I'll try to create a proper program or I'll drop it soon. PS: I have to try the vim pluggin, maybe that could be my email reader in the future. -- Rub?n Poll?n | jabber:meskio at jabber.org -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- No vamos a reivindicar nada, no vamos a pedir nada. Tomaremos, okuparemos. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/69b5cf65/attachment.pgp>
[notmuch] Notmuch doesn't index new mails
Hi all, after setting up notmuch, initially indexing all my mail, and removing the inbox and unread tags thereafter, now I recognize that notmuch doesn't index new mail. --8<---cut here---start->8--- % notmuch new --verbose No new mail---and that's not much. --8<---cut here---end--->8--- I did check that there's really new mail. In the man page, it is mentioned, that notmuch skips directories that are read-only. So now all my folders are "drwxrwxr-x mail mail", and I am in the mail group. But still, notmuch doesn't index new mails. I assumed that the mail files also have to be writable. So I changed them to "-rw-rw-r-- mail mail", but still no luck. Any ideas what might be the problem? Bye, Tassilo
[notmuch] Multithreaded access
Hi, I am also toying around with a curses frontend for notmuch :-) One thing that I would really like to have is asynchronous search: I should be able to begin reading mail even while search results are rolling in. At the moment I'm using one read-only database_t* and creating multiple queries off it. There's a background thread[1] slurping up search results at a time, then passes them to the main thread. The main thread also handles the pager. When the user goes to open a thread, it creates a separate query_t so that it can look up the messages and their headers and filenames. It seems to work, but sometimes crashes. I'm wondering if there is something inherently wrong with this design, so that I should try a different approach. A future concern is how to handle tag updates. Could I open the database for writing in one thread, and read-only in another? Peter [1] Actually, I am playing around with Go at the same time so they are really goroutines. Any problems could very well be related to this.
[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values
On Mon, Nov 23, 2009 at 9:34 AM, Karl Wiberg wrote: > On Mon, Nov 23, 2009 at 7:20 AM, Dirk-Jan C. Binnema > wrote: > > > +ssize_t ignored; > > static char msg[] = "Stopping... \n"; > > -write(2, msg, sizeof(msg)-1); > > + > > +ignored = write(2, msg, sizeof(msg)-1); > > interrupted = 1; > > } > > Didn't the "(void)" suggestion work? > > I actually preferred that solution, but unfortunately, it didn't stop gcc from complaining... Best wishes, Dirk. -- next part -- An HTML attachment was scrubbed... URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/7ea82ed8/attachment.htm>
[notmuch] [PATCH] Make search filters handle disjunctive queries.
notmuch-search-filter accepts now accepts an arbitrary query and will group if necessary so that we get tag:inbox AND (gravy OR biscuits) notmuch-search-filter-tag now handles multiple terms. All terms in the query except AND and OR are interpreted as tags. Signed-off-by: Jed Brown --- notmuch.el | 23 ++- 1 files changed, 18 insertions(+), 5 deletions(-) diff --git a/notmuch.el b/notmuch.el index 0cabbe2..43e0566 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1057,15 +1057,28 @@ search." Runs a new search matching only messages that match both the current search results AND the additional query string provided." (interactive "sFilter search: ") - (notmuch-search (concat notmuch-search-query-string " and " query) notmuch-search-oldest-first)) + (let ((grouped-query (if (string-match-p "\\<[oO][rR]\\>" query) (concat "( " query " )") query))) +(notmuch-search (concat notmuch-search-query-string " and " grouped-query) notmuch-search-oldest-first))) -(defun notmuch-search-filter-by-tag (tag) - "Filter the current search results based on a single tag. +(defun notmuch-search-filter-by-tag (query) + "Filter the current search results based on one or more tags. Runs a new search matching only messages that match both the -current search results AND that are tagged with the given tag." +current search results AND that are tagged with the given +expression involving tags. For example, the input + + chicken and (gravy or biscuits) + +will filter the current search by + + tag:chicken and ( tag:gravy or tag:biscuits )" (interactive "sFilter by tag: ") - (notmuch-search (concat notmuch-search-query-string " and tag:" tag) notmuch-search-oldest-first)) + (let ((tagged-query (replace-regexp-in-string "\\([_\+\-]\\|\\w\\)+" + (lambda (match) ; Prepend `tag:' to all matches except AND and OR + (if (string-match-p "\\([aA][nN][dD]\\)\\|\\([oO][rR]\\)" match) + match (concat "tag:" match))) + query))) +(notmuch-search-filter tagged-query))) (defun notmuch () "Run notmuch to display all mail with tag of 'inbox'" -- 1.6.5.3
[notmuch] OpenPGP support
Hi, folks. I know it's a hairy problem, but has anyone started looking into OpenPGP support for notmuch? jamie. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/d315bb63/attachment.pgp>
[notmuch] [PATCH] New function notmuch-search-operate-all: operate on all messages in the current query.
On Mon, 23 Nov 2009 05:14:25 +0100, Carl Worth wrote: > Second, I like that you just used the search string again, (as opposed > to just walking through the buffer looking at thread IDs). That seems > elegant. It was *easy*. > First, this creates a race condition in that the user will rightly > expect to only be adding/removing tags from the visible results. But if > new mail has been incorporated between creating the current view and > running '*' then threads could be tagged that were never seen and that > could be problematic. Agreed and I had also thought of the case you described. Note that Gmail does not solve the race condition. When in summary mode: * Marking a thread as read applies to all messages in the thread. The thread contents are being updated concurrently so you may mark threads you have already seen. * Same story with archiving (aka. remove inbox). * Starring a thread applies to the last message in the thread, this could be a newly arrived message that is not currently displayed. I think that handling a concurrent changes to the match results is a somewhat hard problem. You have to store the message ids of everything in the current query if you want to avoid the race. > Second, since we're in the search view which shows threads, we should > really be operating on threads. But this tag command won't work like the > '+' and '-' commands in this buffer. Those commands will add/remove a > tag to/from every message in the thread[*]. The new '*' command, however > will only be changing tags on messages that match the query. I'm not convinced that we want to operate on the entire thread. Applying the tag only to the matched messages is enough to find the thread, and it may really be desirable to only have it applied to certain messages in the thread. For example, I might have constructed an elaborate query to find five messages, including a couple that are burried in 100-message threads in which case I would definitely not want to tag entire threads. > So I think we should fix both of these issues by looping over each line > of the buffer and calling (notmuch-search-add-tag) or > (notmuch-search-remove-tag). Presumably you don't mean this literally because that would be horribly slow. What you want is to gather up all the message ids in all the threads with at least one message matching the current query (and currently displayed). I think this is only possible if notmuch-search holds message IDs for everything in the matched threads. If we are happy to just tag the matched messages instead of the entire thread, we would only store the message ids for the matched messages. > Oh, here's one: We could add something like "notmuch tag --expecting= > 1/23 " that would not do the tag unless the search string > matched 1 message out of 23 total messages in the thread. Then we could > give a warning to the user. I like this, but it still presents a minor race condition (suppose another client swaps the unread tag on two messages in the same thread). The only way to guarantee that you are operating on the displayed messages is to store their message ids. > That works for the single-thread case, but the warning would be harder > for the user to deal with in the '*' case. Or maybe not---the emacs > function could just stop on the first line with the error and then the > user would see what's going on. If you can implement notmuch tag --expecting with similar efficiency to the present, then I would vote for notifying the user and asking for confirmation if the number of matches has changed. This would be significantly safer than what Gmail does which ought to be sufficient for now given the age of notmuch. Jed
[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values
On Mon, Nov 23, 2009 at 12:11 PM, Dirk-Jan Binnema wrote: > On Mon, Nov 23, 2009 at 9:34 AM, Karl Wiberg wrote: > > > Didn't the "(void)" suggestion work? > > I actually preferred that solution, but unfortunately, it didn't > stop gcc from complaining... Hmpf. I'd argue that that's a gcc bug, forcing the user to use an unnecessarily complicated way to pretend to use the return value. Oh well. -- Karl Wiberg, kha at treskal.com subrabbit.wordpress.com www.treskal.com/kalle
[notmuch] [PATCH] Mac OS X compatibility fixes
Here's a patch that adds private implementations of strndup and getline. They are unconditionally compiled so that compiler errors in these functions can be detected on any platform, even those that provide strndup and getline in the standard library. I'll have a patch that handles the strndup/getline detection later today (I've already done it in SCons, just need to figure out how I want to do it in plain shell for the current configure script).
[notmuch] [PATCH] Add private implementations of strndup and getline.
Add private implementations of strndup and getline for those platforms that don't have them (notably Mac OS X) no matter what preprocessor symbols you define. Signed-off-by: Jeffrey C. Ollie --- lib/xutil.c | 99 +++ lib/xutil.h |6 +++ 2 files changed, 105 insertions(+), 0 deletions(-) diff --git a/lib/xutil.c b/lib/xutil.c index 6fa5eb0..61467f1 100644 --- a/lib/xutil.c +++ b/lib/xutil.c @@ -79,6 +79,105 @@ xstrdup (const char *s) return ret; } +/* Mac OS X don't have strndup even if _GNU_SOURCE is defined */ +char * +_notmuch_strndup (const char *s, size_t n) +{ +size_t len = strlen (s); +char *ret; + +if (len <= n) + return strdup (s); + +ret = malloc(n + 1); +strncpy(ret, s, n); +ret[n] = '\0'; +return ret; +} + +/* getline implementation is copied from glibc. */ + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) +#endif + +ssize_t +_notmuch_getline (char **lineptr, size_t *n, FILE *fp) +{ +ssize_t result; +size_t cur_len = 0; + +if (lineptr == NULL || n == NULL || fp == NULL) +{ + errno = EINVAL; + return -1; +} + +if (*lineptr == NULL || *n == 0) +{ + *n = 120; + *lineptr = (char *) malloc (*n); + if (*lineptr == NULL) + { + result = -1; + goto end; + } +} + +for (;;) +{ + int i; + + i = getc (fp); + if (i == EOF) + { + result = -1; + break; + } + + /* Make enough space for len+1 (for final NUL) bytes. */ + if (cur_len + 1 >= *n) + { + size_t needed_max = + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; + size_t needed = 2 * *n + 1; /* Be generous. */ + char *new_lineptr; + + if (needed_max < needed) + needed = needed_max; + if (cur_len + 1 >= needed) + { + result = -1; + goto end; + } + + new_lineptr = (char *) realloc (*lineptr, needed); + if (new_lineptr == NULL) + { + result = -1; + goto end; + } + + *lineptr = new_lineptr; + *n = needed; + } + + (*lineptr)[cur_len] = i; + cur_len++; + + if (i == '\n') + break; +} +(*lineptr)[cur_len] = '\0'; +result = cur_len ? (ssize_t) cur_len : result; + +end: +return result; +} + char * xstrndup (const char *s, size_t n) { diff --git a/lib/xutil.h b/lib/xutil.h index b973f7d..d13259a 100644 --- a/lib/xutil.h +++ b/lib/xutil.h @@ -39,6 +39,12 @@ char * xstrdup (const char *s); char * +_notmuch_strndup (const char *s, size_t n); + +ssize_t +_notmuch_getline (char **lineptr, size_t *n, FILE *stream); + +char * xstrndup (const char *s, size_t n); void -- 1.6.5.2
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks (was: Notmuch doesn't index new mails)
Tassilo Horn writes: Hi all, I've investigated a bit further. > [notmuch doesn't index new mails although all directories and files > are readable and writable.] In my config, I have: --8<---cut here---start->8--- [database] path=/home/horn/Mail/Dovecot --8<---cut here---end--->8--- In that directory, there are two symlinks pointing to the real mail location in /var/spool/mail: --8<---cut here---start->8--- [horn at localhost][~/Mail/Dovecot][0][5213] [:)] % ll total 0 lrwxrwxrwx 1 horn horn 34 Nov 23 14:49 fastmail -> /var/spool/mail/fastmail/mailboxes lrwxrwxrwx 1 horn horn 29 Nov 23 14:49 uni -> /var/spool/mail/uni/mailboxes --8<---cut here---end--->8--- Whenever I delete those symlinks and created them anew, the new mails get indexed with the next "notmuch new". Of course, I could create a script that does exactly that, but there should be a better way, right? Bye, Tassilo
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks
Twas brillig at 14:55:40 23.11.2009 UTC+01 when tassilo at member.fsf.org did gyre and gimble: TH> Whenever I delete those symlinks and created them anew, the new TH> mails get indexed with the next "notmuch new". Of course, I could TH> create a script that does exactly that, but there should be a TH> better way, right? Probably mail does not get indexed due to mtime checks. Please try whether touch'ing directory with mailboxes makes it work. -- http://fossarchy.blogspot.com/ -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 834 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/45b239ce/attachment.pgp>
[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values
On Mon, 23 Nov 2009 14:19:18 +0100, Karl Wiberg wrote: > On Mon, Nov 23, 2009 at 12:11 PM, Dirk-Jan Binnema > wrote: > > > On Mon, Nov 23, 2009 at 9:34 AM, Karl Wiberg wrote: > > > > > Didn't the "(void)" suggestion work? > > > > I actually preferred that solution, but unfortunately, it didn't > > stop gcc from complaining... > > Hmpf. I'd argue that that's a gcc bug, forcing the user to use an > unnecessarily complicated way to pretend to use the return value. Oh > well. >From the gcc man page: -Wunused-value Warn whenever a statement computes a result that is explicitly not used. To suppress this warning cast the unused expression to void. This includes an expression-statement or the left- hand side of a comma expression that contains no side effects. For example, an expression such as x[i,j] will cause a warning, while x[(void)i,j] will not. This warning is enabled by -Wall. But I'm confused here because I don't currently see any warnings with gcc-4.4.2. Actually this must be a bug because I get no warnings for the blatantly unused malloc(5); with -Wall -Wextra -pedantic. Anyway, if your system headers specify __attribute__((warn_unused_result)) for write, then you could be running into this bug/feature http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35579 Jed
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks
Mikhail Gusarov writes: Hi Mikhail, > TH> Whenever I delete those symlinks and created them anew, the new > TH> mails get indexed with the next "notmuch new". Of course, I could > TH> create a script that does exactly that, but there should be a > TH> better way, right? > > Probably mail does not get indexed due to mtime checks. Please try > whether touch'ing directory with mailboxes makes it work. No, it seems that doesn't help either. First, I only touched the two symlinks. This didn't help. Then I used "find . -type d | xargs touch" to touch all directories inside the directories the symlinks point to. But still no luck. Finally, I deleted the symlinks and created them anew, and then it indexed the 12 new mails that arrived in the meantime. Bye, Tassilo
[notmuch] [PATCH] notmuch.el: Use variable notmuch-search-oldest-first to decide the search order
Make sure we use notmuch-search-oldest-first to decide the how the search result should be displayed. This helps to set the value to nil and have latest mail shown first Signed-off-by: Aneesh Kumar K.V --- notmuch.el |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/notmuch.el b/notmuch.el index af4ceec..5582132 100644 --- a/notmuch.el +++ b/notmuch.el @@ -840,7 +840,8 @@ thread from that buffer can be show when done with this one)." (fset 'notmuch-search-mode-map notmuch-search-mode-map) (defvar notmuch-search-query-string) -(defvar notmuch-search-oldest-first) +(defvar notmuch-search-oldest-first t + "Show the oldest mail first in the search-mode") (defun notmuch-search-scroll-up () "Scroll up, moving point to last message in thread if at end." @@ -1106,7 +1107,7 @@ current search results AND that are tagged with the given tag." (defun notmuch () "Run notmuch to display all mail with tag of 'inbox'" (interactive) - (notmuch-search "tag:inbox" t)) + (notmuch-search "tag:inbox" notmuch-search-oldest-first)) (setq mail-user-agent 'message-user-agent) @@ -1176,7 +1177,7 @@ results for the search terms in that line. (setq folder (notmuch-folder-find-name))) (let ((search (assoc folder notmuch-folders))) (if search - (notmuch-search (cdr search) t + (notmuch-search (cdr search) notmuch-search-oldest-first (defun notmuch-folder () "Show the notmuch folder view and update the displayed counts." -- 1.6.5.2.74.g610f9
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks
Tassilo Horn writes: Hi Mikhail, >> TH> Whenever I delete those symlinks and created them anew, the new >> TH> mails get indexed with the next "notmuch new". Of course, I could >> TH> create a script that does exactly that, but there should be a >> TH> better way, right? >> >> Probably mail does not get indexed due to mtime checks. Please try >> whether touch'ing directory with mailboxes makes it work. > > No, it seems that doesn't help either. Ah, I'm stupid! I don't have to touch the symlinks or the directories inside the locations the symlinks point to, but instead I have to touch the top-level directory where the symlinks are contained in. Then it works as expected, AFAICT. Thanks a lot, Tassilo
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks
On Mon, 23 Nov 2009 15:43:41 +0100, Tassilo Horn wrote: > First, I only touched the two symlinks. Unfortunately, this actually touched the file pointed to by the symlink, if you stat the symlink you will see that mtime did not change. > This didn't help. Then I used > "find . -type d | xargs touch" to touch all directories inside the > directories the symlinks point to. Actually, this would not have followed the symlinks so it does the same thing as before. I think it is actually hard (or not possible) to change mtime on symlinks under Linux. > But still no luck. Finally, I deleted the symlinks and created them > anew, and then it indexed the 12 new mails that arrived in the > meantime. If /var is on the same filesystem, you could use hard links instead of symlinks. Otherwise I would just add the appropriate ln -sf in the hook before notmuch new. The real solution is for notmuch to check mtime of whatever the symlink's target. Jed
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks
Twas brillig at 16:01:41 23.11.2009 UTC+01 when tassilo at member.fsf.org did gyre and gimble: >>> Probably mail does not get indexed due to mtime checks. Please try >>> whether touch'ing directory with mailboxes makes it work. >> No, it seems that doesn't help either. TH> Ah, I'm stupid! I don't have to touch the symlinks or the TH> directories inside the locations the symlinks point to, but instead TH> I have to touch the top-level directory where the symlinks are TH> contained in. Then it works as expected, AFAICT. Really odd. -- http://fossarchy.blogspot.com/ -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 834 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/815c371f/attachment.pgp>
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks
Twas brillig at 16:03:00 23.11.2009 UTC+01 when jed at 59A2.org did gyre and gimble: JB> The real solution is for notmuch to check mtime of whatever the JB> symlink's target. It does exactly this AFACT, stat() everywhere, not lstat(). -- http://fossarchy.blogspot.com/ -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 834 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/c670575f/attachment.pgp>
[notmuch] Notmuch doesn't index new mails when mail location contains symlinks
On Mon, 23 Nov 2009 16:01:41 +0100, Tassilo Horn wrote: > Tassilo Horn writes: > I don't have to touch the symlinks or the directories inside the > locations the symlinks point to, but instead I have to touch the > top-level directory where the symlinks are contained in. Ah, it's slightly more subtle. Notmuch correctly uses stat() instead of lstat() to check whether the link target changed. However, mtime for your mail root directory (containing the symlinks) does not get updated when the target of the symlinks is updated. I think the only way to fix this is to replace the current search (which skips a directory as soon as it's mtime is older than the database) with one that enters all directories so that symlinks are actually followed. Jed
[notmuch] notmuch new: Memory problem
Hi, Thanks for your help. Here is the information you requested: 2009/11/20 Carl Worth : > I'm curious how big your .notmuch directory ended up after this > operation. (And how that compares in size to the total size of your > collection of mail.) I guess you mean these directories: $ du -sh Maildir 2,8GMaildir $ cd Maildir $ du -sh .notmuch 1,1G.notmuch > That's definitely not too much mail. I think you should expect "notmuch > new" currently to index on the order of 10 - 100 messages/sec. > > Your "notmuch new" process should have been reporting a count once per > second as it progressed, (at least until things went wrong). How far did > you see that go? It started quickly, but its speed decreased, and I interrupted it at some 4000 messages, if I remember correctly. Regards Dominik
[notmuch] [patch] Trivial fix for non-root install
Installing as a normal user fails because the bash completion config files try to install into /etc. This trivial patch fixes this. diff --git a/Makefile.config b/Makefile.config index ddc7436..c04d57a 100644 --- a/Makefile.config +++ b/Makefile.config @@ -1,3 +1,2 @@ -prefix = /usr/local -bash_completion_dir = /etc/bash_completion.d +bash_completion_dir = $(prefix)/etc/bash_completion.d CFLAGS += -DHAVE_VALGRIND -Brett.
[notmuch] [patch] Trivial fix for non-root install
Excerpts from Brett Viren's message of Mon Nov 23 16:31:47 +0100 2009: > Installing as a normal user fails because the bash completion config > files try to install into /etc. This trivial patch fixes this. NAK Your patch breaks the more common case of installing as root user. It now installs into /usr/etc where bash completions most likely won't be found. > diff --git a/Makefile.config b/Makefile.config > index ddc7436..c04d57a 100644 > --- a/Makefile.config > +++ b/Makefile.config > @@ -1,3 +1,2 @@ > -prefix = /usr/local > -bash_completion_dir = /etc/bash_completion.d > +bash_completion_dir = $(prefix)/etc/bash_completion.d > CFLAGS += -DHAVE_VALGRIND > > > -Brett. -- Exherbo KDE, X.org maintainer
[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values
Hi Jed, On Mon, Nov 23, 2009 at 4:24 PM, Jed Brown wrote: > > > But I'm confused here because I don't currently see any warnings with > gcc-4.4.2. Actually this must be a bug because I get no warnings for > the blatantly unused > > malloc(5); > Did you try it with -O2? Without optimizations many of the warnings are not issued. Best wishes, Dirk. -- next part -- An HTML attachment was scrubbed... URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/85157f8a/attachment.htm>
[notmuch] notmuch new: Memory problem
Hi, 2009/11/20 Carl Worth : > On Fri, 20 Nov 2009 09:56:50 +0100, Dominik Epple googlemail.com> wrote: >> Is there a problem with the number of my mails? I currently have over >> 40.000 Mails... they live currently in mbox files, I created a Maildir >> with mb2md-3.20.pl. > > I'm suspecting that you have some big files in there, (such as indexes > from some other mail program). We had code in notmuch to detect and > ignore these, but a recent bug had broken that. > > I just fixed this code as of the below commit. So please update and try > again and let us know if things work any better. Ok, one of the problems seems to be solved. One can learn from the info: output that the code actually ignores non-email data. These files are small and fragments of real mail. Obviously the mb2md code made errors there. But I run in a different issue. I have a lot of files in the Maildir which contain base64 encoded binary data. (Some remote site sends my its daily backup logs.) Those files are all of 2.4 megabyte in size. By adding some debug code to notmuch-new.c, I find out that the program becomes very slow and consumes a lot of memory when adding these files. I just killed it when it consumed 2 GByte again. So as you suspected, the problem seems to stem from large files. But those large files are not indices or stuff like that from different mail programs, but they are valid emails which contain a lot of (encoded) binary data. Perhaps we should be able to configure notmuch such that he ignores all mails that match specific pattern (like "Subject: Backup logs from.*") Regards Dominik
[notmuch] [PATCH 1/2] * avoid gcc 4.4.1 compiler warnings due to ignored write return values
On Mon, 23 Nov 2009 18:14:12 +0200, Dirk-Jan Binnema wrote: > Did you try it with -O2? Without optimizations many of the warnings are not > issued. Yes, $ cat > foo.c #include #include int main() { malloc(5); write(2,0,10); return 0; } $ gcc -static -std=c89 -O0 -Wall -Wextra -pedantic -o foo foo.c $ objdump -d -M intel foo |grep -A12 '' 004002a4 : 4002a4: 55 push rbp 4002a5: 48 89 e5movrbp,rsp 4002a8: bf 05 00 00 00 movedi,0x5 4002ad: e8 6e 61 00 00 call 406420 <__libc_malloc> 4002b2: ba 0a 00 00 00 movedx,0xa 4002b7: be 00 00 00 00 movesi,0x0 4002bc: bf 02 00 00 00 movedi,0x2 4002c1: e8 ea a0 00 00 call 40a3b0 <__libc_write> 4002c6: b8 00 00 00 00 moveax,0x0 4002cb: c9 leave 4002cc: c3 ret 4002cd: 90 nop $ gcc -v Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../configure --prefix=/usr --enable-shared --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-threads=posix --mandir=/usr/share/man --infodir=/usr/share/info --enable-__cxa_atexit --disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu --disable-libstdcxx-pch --with-tune=generic Thread model: posix gcc version 4.4.2 (GCC) $ uname -a Linux kunyang 2.6.31-ARCH #1 SMP PREEMPT Tue Nov 10 19:01:40 CET 2009 x86_64 Intel(R) Core(TM)2 Duo CPU P8700 @ 2.53GHz GenuineIntel GNU/Linux Seems fishy. Jed
[notmuch] [PATCH] Return unpropertized strings for filename and message-id
Hi! Here's my first patch. It changes that notmuch-show-get-filename and notmuch-show-get-message-id return simple strings and not propertited strings. Bye, Tassilo --- notmuch.el |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 0cabbe2..c2839c0 100644 --- a/notmuch.el +++ b/notmuch.el @@ -169,7 +169,7 @@ Unlike builtin `next-line' this version accepts no arguments." (if (not (looking-at notmuch-show-message-begin-regexp)) (re-search-backward notmuch-show-message-begin-regexp)) (re-search-forward notmuch-show-id-regexp) -(buffer-substring (match-beginning 1) (match-end 1 +(buffer-substring-no-properties (match-beginning 1) (match-end 1 (defun notmuch-show-get-filename () (save-excursion @@ -177,7 +177,7 @@ Unlike builtin `next-line' this version accepts no arguments." (if (not (looking-at notmuch-show-message-begin-regexp)) (re-search-backward notmuch-show-message-begin-regexp)) (re-search-forward notmuch-show-filename-regexp) -(buffer-substring (match-beginning 1) (match-end 1 +(buffer-substring-no-properties (match-beginning 1) (match-end 1 (defun notmuch-show-set-tags (tags) (save-excursion -- 1.6.5.3
[notmuch] [PATCH] Make search filters handle disjunctive queries.
notmuch-search-filter accepts now accepts an arbitrary query and will group if necessary so that we get tag:inbox AND (gravy OR biscuits) notmuch-search-filter-tag now handles multiple terms. All terms in the query except AND and OR are interpreted as tags. This version has nice regexes and handles NOT. Signed-off-by: Jed Brown --- notmuch.el | 27 ++- 1 files changed, 22 insertions(+), 5 deletions(-) diff --git a/notmuch.el b/notmuch.el index 0cabbe2..fdd30ae 100644 --- a/notmuch.el +++ b/notmuch.el @@ -828,6 +828,10 @@ thread from that buffer can be show when done with this one)." (defvar notmuch-search-query-string) (defvar notmuch-search-oldest-first) +(defvar notmuch-search-boolean-operator-regexp "\\([aA][nN][dD]\\|[oO][rR]\\|[nN][oO][tT]\\)") +(defvar notmuch-search-valid-term-regexp "\\([-+_.[:word:]]+\\)") +(defvar notmuch-search-disjunctive-regexp "\\<[oO][rR]\\>") + (defun notmuch-search-scroll-up () "Scroll up, moving point to last message in thread if at end." (interactive) @@ -1057,15 +1061,28 @@ search." Runs a new search matching only messages that match both the current search results AND the additional query string provided." (interactive "sFilter search: ") - (notmuch-search (concat notmuch-search-query-string " and " query) notmuch-search-oldest-first)) + (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp query) (concat "( " query " )") query))) +(notmuch-search (concat notmuch-search-query-string " and " grouped-query) notmuch-search-oldest-first))) -(defun notmuch-search-filter-by-tag (tag) - "Filter the current search results based on a single tag. +(defun notmuch-search-filter-by-tag (query) + "Filter the current search results based on one or more tags. Runs a new search matching only messages that match both the -current search results AND that are tagged with the given tag." +current search results AND that are tagged with the given +expression involving tags. For example, the input + + chicken and (gravy or biscuits) + +will filter the current search by + + tag:chicken and ( tag:gravy or tag:biscuits )" (interactive "sFilter by tag: ") - (notmuch-search (concat notmuch-search-query-string " and tag:" tag) notmuch-search-oldest-first)) + (let ((tagged-query (replace-regexp-in-string notmuch-search-valid-term-regexp + (lambda (match) ; Prepend `tag:' to all except boolean operators + (if (string-match-p notmuch-search-boolean-operator-regexp match) + match (concat "tag:" match))) + query))) +(notmuch-search-filter tagged-query))) (defun notmuch () "Run notmuch to display all mail with tag of 'inbox'" -- 1.6.5.3
[notmuch] [PATCH] Add tests to configure script to detect strndup and getline
Add some simple tests to the configure script to detect strndup and getline. It's not important that the tests run, just that they compile and link without any errors. Signed-off-by: Jeffrey C. Ollie --- configure | 20 +++- getlinetest.c | 13 + strnduptest.c | 10 ++ 3 files changed, 42 insertions(+), 1 deletions(-) create mode 100644 getlinetest.c create mode 100644 strnduptest.c diff --git a/configure b/configure index b4770ec..44c1700 100755 --- a/configure +++ b/configure @@ -118,6 +118,24 @@ EOF exit 1 fi +if ! gcc -o strnduptest strnduptest.c > /dev/null 2>&1 +then +echo "Checking for strndup... No." +strndup=-Dstrndup=_notmuch_strndup +else +echo "Checking for strndup... Yes." +fi +rm -f strnduptest + +if ! gcc -o getlinetest getlinetest.c > /dev/null 2>&1 +then +echo "Checking for getline... No." +getline=-Dgetline=_notmuch_getline +else +echo "Checking for getline... Yes." +fi +rm -f getlinetest + cat < Makefile.config < +#include + +int main() +{ + ssize_t count = 0; + size_t n = 0; + char **lineptr = NULL; + FILE *stream = NULL; + + count = getline(lineptr, &n, stream); +} diff --git a/strnduptest.c b/strnduptest.c new file mode 100644 index 000..97c7c80 --- /dev/null +++ b/strnduptest.c @@ -0,0 +1,10 @@ +#include + +int main() +{ + char *d; + const char *s = ""; + size_t n = 0; + + d = strndup(s, n); +} -- 1.6.5.2
[notmuch] [patch] Trivial fix for non-root install
Brett Viren on 2009-11-23 10:31:47 -0500: > Installing as a normal user fails because the bash completion config > files try to install into /etc. This trivial patch fixes this. I worked around this by using $DESTDIR as the prefix and unsetting prefix during the install.
[notmuch] [PATCH] Make search filters handle disjunctive queries.
On Mon, 23 Nov 2009 19:07:23 +0100, Jed Brown wrote: > notmuch-search-filter accepts now accepts an arbitrary query and will > group if necessary so that we get > > tag:inbox AND (gravy OR biscuits) > > notmuch-search-filter-tag now handles multiple terms. All terms in the > query except AND and OR are interpreted as tags. Remember to split patches which do more than one thing into separate commits. > + (let ((grouped-query (if (string-match-p notmuch-search-disjunctive-regexp > query) (concat "( " query " )") query))) > +(notmuch-search (concat notmuch-search-query-string " and " > grouped-query) notmuch-search-oldest-first))) Is there some reason not to just always add the parens? > + (let ((tagged-query (replace-regexp-in-string > notmuch-search-valid-term-regexp > + (lambda (match) ; Prepend > `tag:' to all except boolean operators > + (if (string-match-p > notmuch-search-boolean-operator-regexp match) > + match (concat "tag:" > match))) > + query))) This seems useful; how does it deal with the tag completion stuff? -- keith.packard at intel.com -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/59d04243/attachment.pgp>
[notmuch] [PATCH] Make addresses case insensitive for the purpose of constructing replies.
The domain is alway case insensitive, but in principle the username is case sensitive. Few systems actually enforce this so I think a good default is to treat the entire address as case insensitive, it will eliminate a lot of superfluous self-addressed messages and reply from the correct address in these cases. Signed-off-by: Jed Brown --- notmuch-reply.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/notmuch-reply.c b/notmuch-reply.c index 44e1766..cd81e76 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -97,12 +97,12 @@ address_is_users (const char *address, notmuch_config_t *config) size_t i, other_len; primary = notmuch_config_get_user_primary_email (config); -if (strcmp (primary, address) == 0) +if (strcasecmp (primary, address) == 0) return 1; other = notmuch_config_get_user_other_email (config, &other_len); for (i = 0; i < other_len; i++) - if (strcmp (other[i], address) == 0) + if (strcasecmp (other[i], address) == 0) return 1; return 0; -- 1.6.5.3
[notmuch] [PATCH] Make search filters handle disjunctive queries.
On Mon, 23 Nov 2009 10:26:47 -0800, Keith Packard wrote: > Remember to split patches which do more than one thing into separate > commits. These are variants of the same operation, but I'll split in the future. > > + (let ((grouped-query (if (string-match-p > > notmuch-search-disjunctive-regexp query) (concat "( " query " )") query))) > > +(notmuch-search (concat notmuch-search-query-string " and " > > grouped-query) notmuch-search-oldest-first))) > > Is there some reason not to just always add the parens? That's what I did initially, but it's messy to look at in the mode line after applying successive filters. > This seems useful; how does it deal with the tag completion stuff? It doesn't do anything special, but I haven't been following that carefully. My thought was that eventually the regular interactive search and filters, would have semantic completion, e.g. the user enters tag:ab and tags would be completed, but they could also do from:long.unwieldy.addr In filter-by-tag, the natural thing would be to only complete tags, the user would be on their own to spell out AND, OR, and NOT. Unfortunately I'm not familiar enough with elisp to implement this quickly. A closely related issue is managing the address book. I guess the usual advice is to use BBDB. I don't know if it's better to hook into that or for Notmuch to have it's own lightweight approach. I could imagine harvesting addresses of everyone I've sent mail to and giving me a semi-automated way to merge addresses that are likely to point to the same person. Jed
[notmuch] [PATCH] Support multiple configuration files via $NOTMUCH_CONFIG
Excerpts from Alec Berryman's message of Sun Nov 22 06:18:26 +0100 2009: > If present, $NOTMUCH_CONFIG will be used as the configuration file > location. I'm a bit late to the party, but how about adding the more generic NOTMUCH_OPTIONS, and --config-file, -c options to pass the path to the configuration file? -- Exherbo KDE, X.org maintainer
[notmuch] _notmuch_message_create_for_message_id makes extra call to notmuch_database_find_message
Looking at _notmuch_message_create_for_message_id, the first thing it does is call notmuch_database_find_message, but the returned 'message' is never used. I haven't tried, but I suspect this call could just be removed. -- keith.packard at intel.com -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/71f548b8/attachment.pgp>
[notmuch] [PATCH] Stay out of tmp to respect the Maildir spec.
--- notmuch-new.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/notmuch-new.c b/notmuch-new.c index 8172b49..e32b92a 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -159,6 +159,7 @@ add_files_recursive (notmuch_database_t *notmuch, * user specify files to be ignored. */ if (strcmp (entry->d_name, ".") == 0 || strcmp (entry->d_name, "..") == 0 || + strcmp (entry->d_name, "tmp") == 0 || strcmp (entry->d_name, ".notmuch") ==0) { continue; -- 1.6.5.3
[notmuch] [patch] Trivial fix for non-root install
On Mon, Nov 23, 2009 at 04:41:23PM +0100, Ingmar Vanhassel wrote: > Excerpts from Brett Viren's message of Mon Nov 23 16:31:47 +0100 2009: > > Installing as a normal user fails because the bash completion config > > files try to install into /etc. This trivial patch fixes this. > > Your patch breaks the more common case of installing as root user. It > now installs into /usr/etc where bash completions most likely won't be > found. I submitted a patch similar to Ingmar's the other day. I actually feel like the more common case is to install it locally as a local user, especially during early development. jamie. > > diff --git a/Makefile.config b/Makefile.config > > index ddc7436..c04d57a 100644 > > --- a/Makefile.config > > +++ b/Makefile.config > > @@ -1,3 +1,2 @@ > > -prefix = /usr/local > > -bash_completion_dir = /etc/bash_completion.d > > +bash_completion_dir = $(prefix)/etc/bash_completion.d > > CFLAGS += -DHAVE_VALGRIND > > > > > > -Brett. > -- > Exherbo KDE, X.org maintainer > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091123/0ea9b7af/attachment.pgp>
[notmuch] Multithreaded access
On Mon, 23 Nov 2009 22:07:42 +1100, Peter Wang wrote: > I am also toying around with a curses frontend for notmuch :-) > One thing that I would really like to have is asynchronous search: > I should be able to begin reading mail even while search results > are rolling in. Absolutely! I just coded this up on my plane ride home for notmuch.el and it is *fantastic*. It takes notmuch from "OK, as long as your searches don't have a lot of results" to "Blisteringly fast, regardless of what you're doing." And it's not like sup, where you page down and then wait for more search results to page in. Things just keep filling up in the buffer while you're reading and navigating, just as it should be. I'll be cleaning this up and pushing it out soon. I'm very excited about it. > At the moment I'm using one read-only database_t* and creating multiple > queries off it. There's a background thread[1] slurping up search > results at a time, then passes them to the main thread. The main thread > also handles the pager. When the user goes to open a thread, it creates > a separate query_t so that it can look up the messages and their headers > and filenames. Hmmm... in my code with emacs, I'm just using separate processes, (which seems to be working fine). I haven't looked into Xapian's documentation with regard to threads yet, so I can't actually say how well notmuch's library work with threads yet. > A future concern is how to handle tag updates. Could I open the database > for writing in one thread, and read-only in another? Again, I don't know about the threading yet. But you can definitely open the database read-write in one process while also having it be opened read-only in another. -Carl
[notmuch] [PATCH] Stay out of tmp to respect the Maildir spec.
On Mon, 23 Nov 2009 21:57:33 +0100, Jed Brown wrote: > if (strcmp (entry->d_name, ".") == 0 || > strcmp (entry->d_name, "..") == 0 || > + strcmp (entry->d_name, "tmp") == 0 || > strcmp (entry->d_name, ".notmuch") ==0) Thanks, Jed! I've pushed this now. And sorry about any "file not found" errors anybody is stuck with now. We'll need to add support for cleaning those up soon, (which is the same as supporting deleted mail). -Carl
[notmuch] [PATCH] Make addresses case insensitive for the purpose of constructing replies.
On Mon, 23 Nov 2009 19:29:52 +0100, Jed Brown wrote: > The domain is alway case insensitive, but in principle the username is > case sensitive. Few systems actually enforce this so I think a good > default is to treat the entire address as case insensitive, it will > eliminate a lot of superfluous self-addressed messages and reply from > the correct address in these cases. Good call. I've pushed this out now. -Carl
[notmuch] interesting project!
On Mon, 23 Nov 2009 09:08:34 +0200, Dirk-Jan C. Binnema wrote: > Well, the counter point to the OOM-problems is that is that in many programs, > the 'malloc returns NULL'-case is often not very well tested (because it's > rather hard to test), and that at least on Linux, it's unlikely that malloc > ever does return NULL. Lennart Poettering wrote this up in some more > detail[1]. Of course, the requirements for notmuch may be a bit different and > I definitely don't want to suggest any radical change here after only finding > out about notmuch a few days ago :) No problem. I'm glad to discuss things. That's how I learn and find out whether my decisions are sound or not. :-) I agree that trying to support OOM doesn't make sense without testing. But that's why I want to test notmuch with memory-fault injection. We've been doing this with the cairo library with good success for a while. As for "unlikely that malloc ever returns NULL", that's simply a system-configuration away (just turn off overcommit). And I can imagine notmuch being used in lots of places, (netbooks, web servers, etc.), so I do want to make it as robust as possible. > (BTW, there is a hashtable implementation in libc, (hcreate(3) etc.). Is that > one not sufficiently 'talloc-friendly'? It's not very user-friendly, but > that's another matter) Thanks for mentioning the hash table. The hash table is one of the few things that I *am* using from glib right now in notmuch. It's got a couple of bizarre things about it: 1. The simpler-appearing g_hash_table_new function is useless for common cases like hashing strings. It will just leak memory. So g_hash_table_new_full is the only one worth using. 2. There are two lookup functions, g_hash_table_lookup, and g_hash_table_lookup_extended. And a program like notmuch really does use the hash table in two ways. In the simpler case, we're using the hash to simply implement a set, (such as avoiding duplicates in a set of tags). In the more complex case, we're associating actual objects with the keys, (such as when linking messages together into a tree for the thread). So, it might make sense if a hash-table interface supported these two modes well. What's bizarre about GHashTable though, is that in the "just a set" case, we only use NULL as the value when inserting. And distinguish "previously inserted with NULL" from "never inserted" is the one thing that g_hash_table_lookup can't do. So I've only found that I could ever use g_hash_table_lookup_extended, (and pass a pair of NULLs for the return arguments I don't need). Fortunately, Eric Anholt spent *his* flight home coding up an nice implementation of an open-addressed hash designed specifically to be a tiny little implementation suitable for copying directly into project. He's testing it with Mesa now, and I might pull it into notmuch later. > I could imagine the string functions could replace the ones in talloc. There > are many more string functions, e.g., for handling file names / paths, which > are quite useful. Then there are wrappers for gcc'isms (G_UNLIKELY etc.) that > would make the ones in notmuch unneeded, and a lot of compatibility things > like G_DIR_SEPARATOR. And the datastructures (GSlice/GList/GHashtable) are > nice. The UTF8 functionality might come in handy. Yes. The portability stuff I think is actually interesting. I've thought it really might make sense to have something that gave you *just* that, (without a main loop, an object system, several memory allocators or pieces for making your own memory allocators, etc). I haven't had a chance to look into gnulib yet, but I'd like to. As for a list, I almost always find it cleaner to be able to just have my own list data structures, (to avoid casts, etc.). And for a hash table, I'm interested in what Eric's doing. I'm really not prejudiced against using code that's already been written, (in spite of what might appear I don't feel the need to re-solve every problem that's already been solved). But I have long thought that we could have better support for a "C programmers toolkit" of commonly needed things than we have before. I definitely like the idea of having tiny, focused libraries that do one thing and do it well, (and maybe even some things so tiny that they are actually designed to be copied into the application---like with gnulib and with Eric's new hash table). > Anyway, I was just curious, people have survived without GLib before, and if > you dislike the OOM-strategy, it's a bit of a no-no of course. Thanks for understanding. :-) And I enjoy the conversation, -Carl
[notmuch] notmuch 'index' mode.
On Sun, 22 Nov 2009 23:18:33 -0800, Keith Packard wrote: > On Mon, 23 Nov 2009 07:06:06 +0100, Carl Worth wrote: > > > > * The mode documentation really needs to walk the user through how to > > setup a custom set of folders. > > You can use the standard emacs customization interface, although it's > not exactly well documented there. Additional docs are clearly > indicated. Yes. I think that's a bit too hidden. I'm imagining the case of a new user running notmuch. First, if we're going to allow them to start off from inside emacs rather than the command-line (and why not?) then I think we can pretty much just run "notmuch setup" and "notmuch new" for the user (and those walk the user through things well already. Then, I'd like the user to be seeing the folder view right away (since that's the primary view). We've got support for searching while still indexing, so if we refresh occasionally, the user will be able to see the inbox count just count up while indexing occurs. So what next for the user? We've got lots of empty space in the folder view, so I think what I'd like is to provide some suggestions on search strings to try, and then to make it obvious how to associate a name with a search string. And at that point, I'd like that name to be added to the folder view. And notice, I don't think we'll need to do the "virtual tag" thing of associating a tag name with a search and doing the work of making notmuch maintain the consistency of that tag and search string. It will be much more clean (and shouldn't be any less fast) to just do the searches for the original search terms, (rather than searching for tag terms that were previously applied by searching for the search terms). Then tags become something that are just for manual manipulation. What do you think? > > * It's not opening my "to-me" folder for some reason. (I thought it > > was the '-' at first, but "xorg-board" is working fine). I can debug > > this later. > > It shouldn't work on xorg-board either -- it just skips forward one > 'word' and assumes it's gotten the folder name. Lame programming, I > know. Should be easy to fix. Ah, that's it. So "xorg-board" only looked like it worked because I had a "xorg" folder as well. :-) > What more do you need? Pretty fonts? Icons? A pony? Heh. Just some guidance on what the user can do. It's nice that we have room to do this, (since we don't on the search results view). > Threads or messages? Threads are more expensive to compute, and when the > number is zero, it means the same thing. But, it is surprising to see a > huge number in the folder view and then get only a handful of threads in > the search view. Perhaps if the count is small enough we can go through > and actually figure out how many threads are involved. Maybe something like that. -Carl
[notmuch] notmuch 'index' mode.
On Mon, 23 Nov 2009 19:16:54 -0800, Carl Worth wrote: > So what next for the user? We've got lots of empty space in the folder > view, so I think what I'd like is to provide some suggestions on search > strings to try, and then to make it obvious how to associate a name with > a search string. And at that point, I'd like that name to be added to > the folder view. Right, associate a name for the search from the *search* view instead of the folder view. Then it's just a matter of using that command and typing a name. At that point, you get the new folder (or named search) added to the main window. That's a great plan. > Then tags become something that are just for manual manipulation. What > do you think? So you wouldn't generally end up using tags? And each time you wanted to view a folder you'd really get a new search result? I can see some benefits if you're using time-range based searches (show me all the mail
[notmuch] [PATCH 1/5] make headers locally expandable/collapsable
--- notmuch.el | 18 +++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/notmuch.el b/notmuch.el index fa6e7de..8aee286 100644 --- a/notmuch.el +++ b/notmuch.el @@ -605,7 +605,8 @@ which this thread was originally shown." (end-of-line) ; Inverse video for subject (overlay-put (make-overlay beg (point)) 'face '(:inverse-video t)) -(forward-line 2) +(forward-line 1) +(end-of-line) (let ((beg-hidden (point-marker))) (re-search-forward notmuch-show-header-end-regexp) (beginning-of-line) @@ -619,8 +620,19 @@ which this thread was originally shown." (forward-line) ) (indent-rigidly beg end depth) - (overlay-put (make-overlay beg-hidden end) -'invisible 'notmuch-show-header) +(let ((invis-spec (make-symbol "notmuch-show-header"))) + (add-to-invisibility-spec (cons invis-spec t)) + (overlay-put (make-overlay beg-hidden end) + 'invisible invis-spec) + (goto-char beg) + (forward-line) + (let ((header-button (make-button (line-beginning-position) (line-end-position +(button-put header-button 'invisibility-spec (cons invis-spec t)) +(button-put header-button 'action 'notmuch-toggle-invisible-action) +(button-put header-button 'follow-link t) +(button-put header-button 'help-echo +"mouse-1, RET: Show headers") + )) (goto-char end) (insert "\n") (set-marker beg nil) -- 1.6.5.2
[notmuch] [PATCH 3/5] make a nice function for generating invisibility toggle buttons
I realized I was replicating this code over and over again, so this way if I change my mind about something I only have to do it on one place. --- notmuch.el | 45 - 1 files changed, 16 insertions(+), 29 deletions(-) diff --git a/notmuch.el b/notmuch.el index ed1f7cb..23a07cc 100644 --- a/notmuch.el +++ b/notmuch.el @@ -497,6 +497,13 @@ which this thread was originally shown." (force-window-update) (redisplay t)) +(defun notmuch-configure-invisibility-button (btn invis-spec help-msg) + (button-put btn 'invisibility-spec invis-spec) + (button-put btn 'action 'notmuch-toggle-invisible-action) + (button-put btn 'follow-link t) + (button-put btn 'help-echo (concat "mouse-1, RET: " help-msg)) +) + (defun notmuch-show-markup-citations-region (beg end depth) (goto-char beg) (beginning-of-line) @@ -512,22 +519,13 @@ which this thread was originally shown." (invis-spec (make-symbol "notmuch-citation-region"))) (add-to-invisibility-spec invis-spec) (overlay-put overlay 'invisible invis-spec) - (let ( -(p (point)) + (let ((p (point)) (cite-button-text (concat "[" (number-to-string (count-lines beg-sub (point))) - "-line citation.]")) -) + "-line citation.]"))) (goto-char (- beg-sub 1)) (insert (concat "\n" indent)) -(let ((cite-button (insert-button cite-button-text))) - (button-put cite-button 'invisibility-spec invis-spec) - (button-put cite-button 'action 'notmuch-toggle-invisible-action) - (button-put cite-button 'follow-link t) - (button-put cite-button 'help-echo - "mouse-1, RET: Show citation") - - ) +(notmuch-configure-invisibility-button (insert-button cite-button-text) invis-spec "Show citation") (insert "\n") (goto-char (+ (length cite-button-text) p)) @@ -543,16 +541,9 @@ which this thread was originally shown." (goto-char (- beg-sub 1)) (insert (concat "\n" indent)) -(let ((sig-button (insert-button - (concat "[" (number-to-string sig-lines) - "-line signature.]" - (button-put sig-button 'invisibility-spec invis-spec) - (button-put sig-button 'action - 'notmuch-toggle-invisible-action) - (button-put sig-button 'follow-link t) - (button-put sig-button 'help-echo - "mouse-1, RET: Show signature") - ) +(notmuch-configure-invisibility-button + (insert-button (concat "[" (number-to-string sig-lines) +"-line signature.]")) invis-spec "Show signature") (insert "\n") (goto-char end)) (forward-line @@ -623,13 +614,9 @@ which this thread was originally shown." 'invisible invis-spec) (goto-char beg) (forward-line) - (let ((header-button (make-button (line-beginning-position) (line-end-position -(button-put header-button 'invisibility-spec (cons invis-spec t)) -(button-put header-button 'action 'notmuch-toggle-invisible-action) -(button-put header-button 'follow-link t) -(button-put header-button 'help-echo -"mouse-1, RET: Show headers") - )) + (notmuch-configure-invisibility-button + (make-button (line-beginning-position) (line-end-position)) + (cons invis-spec t) "Show headers")) (goto-char end) (insert "\n") (set-marker beg nil) -- 1.6.5.2
[notmuch] [PATCH 2/5] cleanup a lot of left-overs from the global invis
--- notmuch.el | 36 1 files changed, 0 insertions(+), 36 deletions(-) diff --git a/notmuch.el b/notmuch.el index 8aee286..ed1f7cb 100644 --- a/notmuch.el +++ b/notmuch.el @@ -62,8 +62,6 @@ (define-key map "a" 'notmuch-show-archive-thread) (define-key map "A" 'notmuch-show-mark-read-then-archive-thread) (define-key map "b" 'notmuch-show-toggle-body-read-visible) -(define-key map "c" 'notmuch-show-toggle-citations-visible) -(define-key map "h" 'notmuch-show-toggle-headers-visible) (define-key map "m" 'message-mail) (define-key map "n" 'notmuch-show-next-message) (define-key map "N" 'notmuch-show-mark-read-then-next-open-message) @@ -72,7 +70,6 @@ (define-key map (kbd "C-p") 'notmuch-show-previous-line) (define-key map "q" 'kill-this-buffer) (define-key map "r" 'notmuch-show-reply) -(define-key map "s" 'notmuch-show-toggle-signatures-visible) (define-key map "v" 'notmuch-show-view-all-mime-parts) (define-key map "w" 'notmuch-show-view-raw-message) (define-key map "x" 'kill-this-buffer) @@ -666,39 +663,6 @@ which this thread was originally shown." (notmuch-show-markup-message))) (notmuch-show-hide-markers)) -(defun notmuch-show-toggle-citations-visible () - "Toggle visibility of citations" - (interactive) - (if notmuch-show-citations-visible - (add-to-invisibility-spec 'notmuch-show-citation) -(remove-from-invisibility-spec 'notmuch-show-citation)) - (set 'notmuch-show-citations-visible (not notmuch-show-citations-visible)) - ; Need to force the redisplay for some reason - (force-window-update) - (redisplay t)) - -(defun notmuch-show-toggle-signatures-visible () - "Toggle visibility of signatures" - (interactive) - (if notmuch-show-signatures-visible - (add-to-invisibility-spec 'notmuch-show-signature) -(remove-from-invisibility-spec 'notmuch-show-signature)) - (set 'notmuch-show-signatures-visible (not notmuch-show-signatures-visible)) - ; Need to force the redisplay for some reason - (force-window-update) - (redisplay t)) - -(defun notmuch-show-toggle-headers-visible () - "Toggle visibility of header fields" - (interactive) - (if notmuch-show-headers-visible - (add-to-invisibility-spec 'notmuch-show-header) -(remove-from-invisibility-spec 'notmuch-show-header)) - (set 'notmuch-show-headers-visible (not notmuch-show-headers-visible)) - ; Need to force the redisplay for some reason - (force-window-update) - (redisplay t)) - (defun notmuch-show-toggle-body-read-visible () "Toggle visibility of message bodies of read messages" (interactive) -- 1.6.5.2
[notmuch] [PATCH 4/5] Make bodies locally toggleable
Having actually implemented this, I realized that my initial approach of providing a function to configure a button was wrong. Instead I've replaced that with button types. This then makes it possible to provide the fully expanded view when all threads in a message are unread. It also has the potential to allow global-expansion functions if that is desireable --- notmuch.el | 89 +++ 1 files changed, 47 insertions(+), 42 deletions(-) diff --git a/notmuch.el b/notmuch.el index 23a07cc..af0c487 100644 --- a/notmuch.el +++ b/notmuch.el @@ -497,12 +497,15 @@ which this thread was originally shown." (force-window-update) (redisplay t)) -(defun notmuch-configure-invisibility-button (btn invis-spec help-msg) - (button-put btn 'invisibility-spec invis-spec) - (button-put btn 'action 'notmuch-toggle-invisible-action) - (button-put btn 'follow-link t) - (button-put btn 'help-echo (concat "mouse-1, RET: " help-msg)) -) +(define-button-type 'notmuch-button-invisibility-toggle-type 'action 'notmuch-toggle-invisible-action 'follow-link t) +(define-button-type 'notmuch-button-citation-toggle-type 'help-echo "mouse-1, RET: Show citation" + :supertype 'notmuch-button-invisibility-toggle-type) +(define-button-type 'notmuch-button-signature-toggle-type 'help-echo "mouse-1, RET: Show signature" + :supertype 'notmuch-button-invisibility-toggle-type) +(define-button-type 'notmuch-button-headers-toggle-type 'help-echo "mouse-1, RET: Show headers" + :supertype 'notmuch-button-invisibility-toggle-type) +(define-button-type 'notmuch-button-body-toggle-type 'help-echo "mouse-1, RET: Show message" + :supertype 'notmuch-button-invisibility-toggle-type) (defun notmuch-show-markup-citations-region (beg end depth) (goto-char beg) @@ -525,7 +528,9 @@ which this thread was originally shown." "-line citation.]"))) (goto-char (- beg-sub 1)) (insert (concat "\n" indent)) -(notmuch-configure-invisibility-button (insert-button cite-button-text) invis-spec "Show citation") +(insert-button cite-button-text + 'invisibility-spec invis-spec + :type 'notmuch-button-citation-toggle-type) (insert "\n") (goto-char (+ (length cite-button-text) p)) @@ -541,9 +546,11 @@ which this thread was originally shown." (goto-char (- beg-sub 1)) (insert (concat "\n" indent)) -(notmuch-configure-invisibility-button - (insert-button (concat "[" (number-to-string sig-lines) -"-line signature.]")) invis-spec "Show signature") +(let ((sig-button-text (concat "[" (number-to-string sig-lines) + "-line signature.]"))) + (insert-button sig-button-text 'invisibility-spec invis-spec + :type 'notmuch-button-signature-toggle-type) + ) (insert "\n") (goto-char end)) (forward-line @@ -572,16 +579,19 @@ which this thread was originally shown." (while (< (point) end) (notmuch-show-markup-part beg end depth -(defun notmuch-show-markup-body (depth) +(defun notmuch-show-markup-body (depth btn) (re-search-forward notmuch-show-body-begin-regexp) (forward-line) (let ((beg (point-marker))) (re-search-forward notmuch-show-body-end-regexp) (let ((end (copy-marker (match-beginning 0 (notmuch-show-markup-parts-region beg end depth) - (if (not (notmuch-show-message-unread-p)) - (overlay-put (make-overlay beg end) - 'invisible 'notmuch-show-body-read)) + (let ((invis-spec (make-symbol "notmuch-show-body-read"))) +(overlay-put (make-overlay beg end) + 'invisible invis-spec) +(button-put btn 'invisibility-spec invis-spec) +(if (not (notmuch-show-message-unread-p)) +(add-to-invisibility-spec invis-spec))) (set-marker beg nil) (set-marker end nil) ))) @@ -589,10 +599,12 @@ which this thread was originally shown." (defun notmuch-show-markup-header (depth) (re-search-forward notmuch-show-header-begin-regexp) (forward-line) - (let ((beg (point-marker))) + (let ((beg (point-marker)) +(btn nil)) (end-of-line) ; Inverse video for subject (overlay-put (make-overlay beg (point)) 'face '(:inverse-video t)) +(setq btn (make-button beg (point) :type 'notmuch-button-body-toggle-type)) (forward-line 1) (end-of-line) (let ((beg-hidden (point-marker))) @@ -614,23 +626,25 @@ which this thread was originally shown." 'invisible invis-spec) (goto-char b
[notmuch] [PATCH 5/5] Remove the global expand body keymapping
--- notmuch.el |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/notmuch.el b/notmuch.el index af0c487..907df2c 100644 --- a/notmuch.el +++ b/notmuch.el @@ -61,7 +61,6 @@ ; overlays-at to query and manipulate the current overlay. (define-key map "a" 'notmuch-show-archive-thread) (define-key map "A" 'notmuch-show-mark-read-then-archive-thread) -(define-key map "b" 'notmuch-show-toggle-body-read-visible) (define-key map "m" 'message-mail) (define-key map "n" 'notmuch-show-next-message) (define-key map "N" 'notmuch-show-mark-read-then-next-open-message) -- 1.6.5.2