[notmuch] [PATCH 2/2] notmuch.el: convert sparse keymap to a list in notmuch-substitute-one-command-key-with-prefix
From: David BremnerThe previous version would crash when a key was bound to a sparse keymap, since apparently these are not straightforward lists. The usage of map-keymap is a bit obscure: it only has side-effects, no return value. --- notmuch.el |8 ++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 8df0778..7b058de 100644 --- a/notmuch.el +++ b/notmuch.el @@ -846,8 +846,12 @@ For a mouse binding, return nil." (if (mouse-event-p key) nil (if (keymapp action) - (let ((substitute (apply-partially 'notmuch-substitute-one-command-key-with-prefix (notmuch-prefix-key-description key - (mapconcat substitute (cdr action) "\n")) + (let ((substitute (apply-partially 'notmuch-substitute-one-command-key-with-prefix (notmuch-prefix-key-description key))) + (as-list)) + (map-keymap (lambda (a b) + (push (cons a b) as-list)) + action) + (mapconcat substitute as-list "\n")) (concat prefix (format-kbd-macro (vector key)) "\t" (notmuch-documentation-first-line action)) -- 1.6.5
[notmuch] [PATCH 1/2] notmuch.el: add a submap (on "z" for "ztash") to stash things.
From: David BremnerProvide key bindings for stuffing everything with a notmuch-show-get-foo function into the emacs kill-ring as text. Currently this is just message-id, filename, and tags. --- notmuch.el | 31 +++ 1 files changed, 31 insertions(+), 0 deletions(-) diff --git a/notmuch.el b/notmuch.el index 97914f2..8df0778 100644 --- a/notmuch.el +++ b/notmuch.el @@ -51,6 +51,17 @@ (require 'mm-view) (require 'message) +(defvar notmuch-show-stash-map + (let ((map (make-sparse-keymap))) +(define-key map "m" 'notmuch-show-stash-message-id) +(define-key map "F" 'notmuch-show-stash-filename) +(define-key map "T" 'notmuch-show-stash-tags) +map) + "Submap for stash commands" + ) + +(fset 'notmuch-show-stash-map notmuch-show-stash-map) + (defvar notmuch-show-mode-map (let ((map (make-sparse-keymap))) (define-key map "?" 'notmuch-help) @@ -78,6 +89,7 @@ (define-key map "n" 'notmuch-show-next-message) (define-key map (kbd "DEL") 'notmuch-show-rewind) (define-key map " " 'notmuch-show-advance-marking-read-and-archiving) +(define-key map "z" 'notmuch-show-stash-map) map) "Keymap for \"notmuch show\" buffers.") (fset 'notmuch-show-mode-map notmuch-show-mode-map) @@ -920,6 +932,25 @@ All currently available key bindings: :options '(hl-line-mode) :group 'notmuch) +(defun notmuch-show-do-stash (text) +(kill-new text) +(message (concat "Saved " text))) + +(defun notmuch-show-stash-message-id () + "Copy message-id of current message to kill-ring." + (interactive) + (notmuch-show-do-stash (notmuch-show-get-message-id))) + +(defun notmuch-show-stash-filename () + "Copy filename of current message to kill-ring." + (interactive) + (notmuch-show-do-stash (notmuch-show-get-filename))) + +(defun notmuch-show-stash-tags () + "Copy tags of current message to kill-ring as a comma separated list." + (interactive) + (notmuch-show-do-stash (mapconcat 'identity (notmuch-show-get-tags) ","))) + ; Make show mode a bit prettier, highlighting URLs and using word wrap (defun notmuch-show-pretty-hook () -- 1.6.5
[notmuch] (no subject)
Thanks to Micah Anderson on IRC for pointing out that the previous version of this patch broke '?' in notmuch-show mode. This was arguably a bug in the notmuch help code, fixed in patch 2 of the series. I wouldn't be surprised if 'map-keymap' could be used other places in the code, but I kept things minimal-ish. The first patch has been revised to actually include documentation strings (blush).
[notmuch] [PATCH 3/3] Allow folders with no messages to be elided from list.
This makes it easier to see folders with messages. Eliding empty folders is togged with the 'e' binding. Signed-off-by: Keith Packard --- lib/Makefile.local |1 + lib/notmuch.h | 11 +++ lib/query.cc | 41 + notmuch-new.c |1 + notmuch.el | 29 - 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index a7562c9..e42f533 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -2,6 +2,7 @@ dir=lib extra_cflags += -I$(dir) libnotmuch_c_srcs =\ + $(dir)/date.c \ $(dir)/libsha1.c\ $(dir)/message-file.c \ $(dir)/messages.c \ diff --git a/lib/notmuch.h b/lib/notmuch.h index 60834fb..f24da18 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -94,6 +94,7 @@ typedef enum _notmuch_status { NOTMUCH_STATUS_NULL_POINTER, NOTMUCH_STATUS_TAG_TOO_LONG, NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW, +NOTMUCH_STATUS_INVALID_DATE, NOTMUCH_STATUS_LAST_STATUS } notmuch_status_t; @@ -929,6 +930,16 @@ notmuch_tags_advance (notmuch_tags_t *tags); void notmuch_tags_destroy (notmuch_tags_t *tags); +/* Convert a string into a time range + * + * This parses the provided string, providing two time values + * representing the begining and end of the period. It + * returns NOTMUCH_STATUS_INVALID_DATE if the string could not be + * parsed, otherwise it return NOTMUCH_STATUS_SUCCESS + */ +notmuch_status_t +notmuch_date(const char *text, time_t *first, time_t *last); + NOTMUCH_END_DECLS #endif diff --git a/lib/query.cc b/lib/query.cc index 9106b92..f511146 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -47,6 +47,47 @@ struct _notmuch_threads { const char *thread_id; }; +static char * +notmuch_query_extract_word(notmuch_query_t *query, char *leader) +{ + char*token = strstr(query->query_string, leader); + int len = strlen(leader); + char*space; + char*word; + char*query_string; + + if (!token) + return NULL; + space = strchr(token, ' '); + if (!space) + space = token + strlen(token); + word = talloc_strndup(query, token + len, space - token - len); + query_string = talloc(query, strlen(query->query_string) - (space - token)); + strncpy(query_string, query->query_string, token - query->query_string); + strcat(query_string, space); + query->query_string = query_string; + return word; +} + +static notmuch_status_t +notmuch_query_edit(notmuch_query_t *query) +{ + char*before, *after; + time_t before_first, before_last, after_first, after_last; + + /* edit date range */ + before = notmuch_query_extract_word(query, "before:"); + if (notmuch_date(before, _first, _last) != NOTMUCH_STATUS_SUCCESS) + before = NULL; + after = notmuch_query_extract_word(query, "after:"); + if (notmuch_date(after, _first, _last) != NOTMUCH_STATUS_SUCCESS) + after = NULL; + + if (before && after) { + + } +} + notmuch_query_t * notmuch_query_create (notmuch_database_t *notmuch, const char *query_string) diff --git a/notmuch-new.c b/notmuch-new.c index 9d20616..3974b28 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -264,6 +264,7 @@ add_files_recursive (notmuch_database_t *notmuch, case NOTMUCH_STATUS_TAG_TOO_LONG: case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: case NOTMUCH_STATUS_LAST_STATUS: + case NOTMUCH_STATUS_INVALID_DATE: INTERNAL_ERROR ("add_message returned unexpected value: %d", status); goto DONE; } diff --git a/notmuch.el b/notmuch.el index c02adc6..73917e7 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1379,6 +1379,7 @@ current search results AND that are tagged with the given tag." (define-key map "x" 'kill-this-buffer) (define-key map "q" 'kill-this-buffer) (define-key map "m" 'message-mail) +(define-key map "e" 'notmuch-folder-show-empty-toggle) (define-key map ">" 'notmuch-folder-last) (define-key map "<" 'notmuch-folder-first) (define-key map "=" 'notmuch-folder) @@ -1455,14 +1456,32 @@ Currently available key bindings: (goto-char (point-max)) (forward-line -1)) +(defun notmuch-folder-count (search) + (car (process-lines notmuch-command "count" search))) + +(setq notmuch-folder-show-empty t) + +(defun notmuch-folder-show-empty-toggle () + "Toggle the listing of empty folders" + (interactive) + (setq notmuch-folder-show-empty (not notmuch-folder-show-empty)) + (notmuch-folder)) + (defun notmuch-folder-add (folders) (if folders - (let ((name (car (car folders))) + (let* ((name (car (car folders))) (inhibit-read-only t) -
[notmuch] [PATCH 2/3] Look at whitespace to separate folder name from count
This allows folder names to contain any non-blank characters Signed-off-by: Keith Packard --- notmuch.el |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 3dbb64a..c02adc6 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1469,8 +1469,8 @@ Currently available key bindings: (save-excursion (beginning-of-line) (let ((beg (point))) - (forward-word) - (filter-buffer-substring beg (point) + (re-search-forward "\\([ \t]*[^ \t]+\\)") + (filter-buffer-substring (match-beginning 1) (match-end 1) (defun notmuch-folder-show-search ( folder) "Show a search window for the search related to the specified folder." -- 1.6.5.4
[notmuch] [PATCH 1/3] Add 'm' and ' ' bindings to notmuch-folder view
This allows the user to compose new mail from the folder view, and also to use to show the current folder. Signed-off-by: Keith Packard --- notmuch.el |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/notmuch.el b/notmuch.el index 97914f2..3dbb64a 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1378,12 +1378,14 @@ current search results AND that are tagged with the given tag." (define-key map "?" 'notmuch-help) (define-key map "x" 'kill-this-buffer) (define-key map "q" 'kill-this-buffer) +(define-key map "m" 'message-mail) (define-key map ">" 'notmuch-folder-last) (define-key map "<" 'notmuch-folder-first) (define-key map "=" 'notmuch-folder) (define-key map "s" 'notmuch-search) (define-key map [mouse-1] 'notmuch-folder-show-search) (define-key map (kbd "RET") 'notmuch-folder-show-search) +(define-key map " " 'notmuch-folder-show-search) (define-key map "p" 'notmuch-folder-previous) (define-key map "n" 'notmuch-folder-next) map) -- 1.6.5.4
[notmuch] update on delete/rename support
On Sat, 26 Dec 2009 14:20:38 -0500, micah anderson wrote: > > >You may have to wrap your "notmuch new" call in a "notmuch save", > >"notmuch restore" pair if you discover things coming back to your > >inbox > > do you mean "notmuch dump" here instead of "notmuch save"? Yes, sorry. > I'm trying to unpack what you are saying here. Are you saying that if > you are getting things coming back into your inbox, and you have not > applied your "lazy restore" patch, then you would need a script to check > your email which does: > > notmuch dump > /tmp/notmuch.dump > offlineimap > notmuch new > notmuch restore < /tmp/notmuch.dump The script is the same in both cases, but without my patch, it takes more like 10 minutes for me. d
[notmuch] update on delete/rename support
On Sat, 26 Dec 2009 12:12:09 -0400, David Bremner wrote: >You may have to wrap your "notmuch new" call in a "notmuch save", >"notmuch restore" pair if you discover things coming back to your inbox. do you mean "notmuch dump" here instead of "notmuch save"? > The whole dump-maildirsync-new-restore cycle takes about 30s for me > check mail, a bit longer if there is actually new mail. I'm trying to unpack what you are saying here. Are you saying that if you are getting things coming back into your inbox, and you have not applied your "lazy restore" patch, then you would need a script to check your email which does: notmuch dump > /tmp/notmuch.dump offlineimap notmuch new notmuch restore < /tmp/notmuch.dump micah
[notmuch] update on delete/rename support
On Sat, 26 Dec 2009 00:21:15 -0500, Jameson Graef Rollins wrote: > Hey, folks. I was wondering if there was an update on getting support > for mail deleting and moving/renaming into notmuch. I wanted to try to > push on it a little bit since I believe that support for deleting/moving > messages is the most important outstanding issue at the moment. As far as I know Carl is working away on this. In the meantime, I am using Mikhail Gusarov's patch id:1259788526-14205-1-git-send-email-dottedmag at dottedmag.net It is not perfect performance-wise, and iirc, it only deals with renames, but it does let me use notmuch as my main mail reader. You may have to wrap your "notmuch new" call in a "notmuch save", "notmuch restore" pair if you discover things coming back to your inbox. This is less onerous if you use my "lazy restore" patch. id:1260310063-11731-1-git-send-email-david at tethera.net The whole dump-maildirsync-new-restore cycle takes about 30s for me check mail, a bit longer if there is actually new mail. David
[notmuch] update on delete/rename support
On Sat, 26 Dec 2009 12:12:09 -0400, David Bremner wrote: > On Sat, 26 Dec 2009 00:21:15 -0500, Jameson Graef Rollins finestructure.net> wrote: > > Hey, folks. I was wondering if there was an update on getting support > > for mail deleting and moving/renaming into notmuch. I wanted to try to > > push on it a little bit since I believe that support for deleting/moving > > messages is the most important outstanding issue at the moment. > > As far as I know Carl is working away on this. Yes. I've got a series of about 20 commits reworking the internals a bit, and then one patch past that that I still need to break down into several clean commits. I think I've got things working now to cleanly detect file deletion. And the only bug that I *know* is still there is a performance bug, (it's somehow spending time doing something silly with known messages when it should just march along and only do real work with new and deleted files). Anyway, I hope to have something to actually publish early next week. Please forgive me for not sharing more as I go along here. The patches change the storage within the database, so one could be left in a very unpleasant state if using patches that don't match the database storage that we'll be using in the end. -Carl -- 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/20091226/340eddf0/attachment.pgp>
[notmuch] update on delete/rename support
Hey, folks. I was wondering if there was an update on getting support for mail deleting and moving/renaming into notmuch. I wanted to try to push on it a little bit since I believe that support for deleting/moving messages is the most important outstanding issue at the moment. I finally got around to really trying notmuch (xmas present to myself) and I'm finding the inability to delete/move messages quite problematic. Currently, my inbox consists of a local maildir that is sync'd to a remote IMAP mailbox via offlineimap. As I go through my inbox I either move mail to an archive, or delete unwanted messages. A system like this obviously requires that my MUA supports moving and deleting messages. I know a lot of people have similar setups, and in fact some have brought it up on this list. Probably the main issues here is that remote IMAP stores generally do not have unlimited space, and a lot of people use remote IMAP stores. Even for those that can just pull all their mail directly, local mail stores are generally not unlimited either, and the ability to completely purge messages is still important. It seems to me (without really knowing what's involved) that for notmuch the main issue is really handling deleted messages. Notmuch handles new mail fine (obviously) and moved/renamed messages are really just messages that are deleted while an identical but differently named new message shows up somewhere else, right? Would someone who understands what's going on under the hood be up for giving a brief explanation about what the issues involved are? jamie. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20091226/e5f9aea0/attachment-0001.pgp>
[notmuch] [PATCH 3/3] Allow folders with no messages to be elided from list.
This makes it easier to see folders with messages. Eliding empty folders is togged with the 'e' binding. Signed-off-by: Keith Packard kei...@keithp.com --- lib/Makefile.local |1 + lib/notmuch.h | 11 +++ lib/query.cc | 41 + notmuch-new.c |1 + notmuch.el | 29 - 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/lib/Makefile.local b/lib/Makefile.local index a7562c9..e42f533 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -2,6 +2,7 @@ dir=lib extra_cflags += -I$(dir) libnotmuch_c_srcs =\ + $(dir)/date.c \ $(dir)/libsha1.c\ $(dir)/message-file.c \ $(dir)/messages.c \ diff --git a/lib/notmuch.h b/lib/notmuch.h index 60834fb..f24da18 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -94,6 +94,7 @@ typedef enum _notmuch_status { NOTMUCH_STATUS_NULL_POINTER, NOTMUCH_STATUS_TAG_TOO_LONG, NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW, +NOTMUCH_STATUS_INVALID_DATE, NOTMUCH_STATUS_LAST_STATUS } notmuch_status_t; @@ -929,6 +930,16 @@ notmuch_tags_advance (notmuch_tags_t *tags); void notmuch_tags_destroy (notmuch_tags_t *tags); +/* Convert a string into a time range + * + * This parses the provided string, providing two time values + * representing the begining and end of the period. It + * returns NOTMUCH_STATUS_INVALID_DATE if the string could not be + * parsed, otherwise it return NOTMUCH_STATUS_SUCCESS + */ +notmuch_status_t +notmuch_date(const char *text, time_t *first, time_t *last); + NOTMUCH_END_DECLS #endif diff --git a/lib/query.cc b/lib/query.cc index 9106b92..f511146 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -47,6 +47,47 @@ struct _notmuch_threads { const char *thread_id; }; +static char * +notmuch_query_extract_word(notmuch_query_t *query, char *leader) +{ + char*token = strstr(query-query_string, leader); + int len = strlen(leader); + char*space; + char*word; + char*query_string; + + if (!token) + return NULL; + space = strchr(token, ' '); + if (!space) + space = token + strlen(token); + word = talloc_strndup(query, token + len, space - token - len); + query_string = talloc(query, strlen(query-query_string) - (space - token)); + strncpy(query_string, query-query_string, token - query-query_string); + strcat(query_string, space); + query-query_string = query_string; + return word; +} + +static notmuch_status_t +notmuch_query_edit(notmuch_query_t *query) +{ + char*before, *after; + time_t before_first, before_last, after_first, after_last; + + /* edit date range */ + before = notmuch_query_extract_word(query, before:); + if (notmuch_date(before, before_first, before_last) != NOTMUCH_STATUS_SUCCESS) + before = NULL; + after = notmuch_query_extract_word(query, after:); + if (notmuch_date(after, after_first, after_last) != NOTMUCH_STATUS_SUCCESS) + after = NULL; + + if (before after) { + + } +} + notmuch_query_t * notmuch_query_create (notmuch_database_t *notmuch, const char *query_string) diff --git a/notmuch-new.c b/notmuch-new.c index 9d20616..3974b28 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -264,6 +264,7 @@ add_files_recursive (notmuch_database_t *notmuch, case NOTMUCH_STATUS_TAG_TOO_LONG: case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: case NOTMUCH_STATUS_LAST_STATUS: + case NOTMUCH_STATUS_INVALID_DATE: INTERNAL_ERROR (add_message returned unexpected value: %d, status); goto DONE; } diff --git a/notmuch.el b/notmuch.el index c02adc6..73917e7 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1379,6 +1379,7 @@ current search results AND that are tagged with the given tag. (define-key map x 'kill-this-buffer) (define-key map q 'kill-this-buffer) (define-key map m 'message-mail) +(define-key map e 'notmuch-folder-show-empty-toggle) (define-key map 'notmuch-folder-last) (define-key map 'notmuch-folder-first) (define-key map = 'notmuch-folder) @@ -1455,14 +1456,32 @@ Currently available key bindings: (goto-char (point-max)) (forward-line -1)) +(defun notmuch-folder-count (search) + (car (process-lines notmuch-command count search))) + +(setq notmuch-folder-show-empty t) + +(defun notmuch-folder-show-empty-toggle () + Toggle the listing of empty folders + (interactive) + (setq notmuch-folder-show-empty (not notmuch-folder-show-empty)) + (notmuch-folder)) + (defun notmuch-folder-add (folders) (if folders - (let ((name (car (car folders))) + (let* ((name (car (car folders))) (inhibit-read-only t) -
[notmuch] [PATCH 2/2] notmuch.el: convert sparse keymap to a list in notmuch-substitute-one-command-key-with-prefix
From: David Bremner brem...@unb.ca The previous version would crash when a key was bound to a sparse keymap, since apparently these are not straightforward lists. The usage of map-keymap is a bit obscure: it only has side-effects, no return value. --- notmuch.el |8 ++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 8df0778..7b058de 100644 --- a/notmuch.el +++ b/notmuch.el @@ -846,8 +846,12 @@ For a mouse binding, return nil. (if (mouse-event-p key) nil (if (keymapp action) - (let ((substitute (apply-partially 'notmuch-substitute-one-command-key-with-prefix (notmuch-prefix-key-description key - (mapconcat substitute (cdr action) \n)) + (let ((substitute (apply-partially 'notmuch-substitute-one-command-key-with-prefix (notmuch-prefix-key-description key))) + (as-list)) + (map-keymap (lambda (a b) + (push (cons a b) as-list)) + action) + (mapconcat substitute as-list \n)) (concat prefix (format-kbd-macro (vector key)) \t (notmuch-documentation-first-line action)) -- 1.6.5 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch