[notmuch] [PATCH 2/2] notmuch.el: convert sparse keymap to a list in notmuch-substitute-one-command-key-with-prefix

2009-12-26 Thread da...@tethera.net
From: David Bremner 

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] [PATCH 1/2] notmuch.el: add a submap (on "z" for "ztash") to stash things.

2009-12-26 Thread da...@tethera.net
From: David Bremner 

Provide 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)

2009-12-26 Thread da...@tethera.net
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.

2009-12-26 Thread Keith Packard
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

2009-12-26 Thread Keith Packard
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

2009-12-26 Thread Keith Packard
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

2009-12-26 Thread David Bremner
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

2009-12-26 Thread micah anderson

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

2009-12-26 Thread David Bremner
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

2009-12-26 Thread Carl Worth
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

2009-12-26 Thread Jameson Graef Rollins
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.

2009-12-26 Thread Keith Packard
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

2009-12-26 Thread david
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