[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters
Define a keymap for attachment buttons to allow multiple actions.
Define 3 possible actions:
save attachment: exactly as currently,
view attachment: uses mailcap entry,
view attachment with user chosen program

Keymap on a button is: s for save, v for view and o for view with
other program. Default (i.e. enter or mouse button) is save but this
is configurable in notmuch customize.

One implementation detail: the view attachment function forces all
attachments to be "displayed" using mailcap even if emacs could
display them itself. Thus, for example, text/html appears in a browser
and text/plain asks whether to save (on a standard debian setup)
---
 emacs/notmuch-show.el |  106 ++---
 1 files changed, 82 insertions(+), 24 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 03c1f6b..0aaaf79 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -281,10 +281,21 @@ message at DEPTH in the current thread."
(run-hooks 'notmuch-show-markup-headers-hook)

 (define-button-type 'notmuch-show-part-button-type
-  'action 'notmuch-show-part-button-action
+  'action 'notmuch-show-part-button-default
+  'keymap 'notmuch-show-part-button-map
   'follow-link t
   'face 'message-mml)

+(defvar notmuch-show-part-button-map
+  (let ((map (make-sparse-keymap)))
+   (set-keymap-parent map button-map)
+   (define-key map "s" 'notmuch-show-part-button-save)
+   (define-key map "v" 'notmuch-show-part-button-view)
+   (define-key map "o" 'notmuch-show-part-button-interactively-view)
+map)
+  "Submap for button commands")
+(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
+
 (defun notmuch-show-insert-part-header (nth content-type declared-type 
 name comment)
   (let ((button))
 (setq button
@@ -299,29 +310,48 @@ message at DEPTH in the current thread."
   " ]")
   :type 'notmuch-show-part-button-type
   :notmuch-part nth
-  :notmuch-filename name))
+  :notmuch-filename name
+  :notmuch-content-type content-type))
 (insert "\n")
 ;; return button
 button))

 ;; Functions handling particular MIME parts.

-(defun notmuch-show-save-part (message-id nth  filename)
-  (let ((process-crypto notmuch-show-process-crypto))
-(with-temp-buffer
-  (setq notmuch-show-process-crypto process-crypto)
-  ;; Always acquires the part via `notmuch part', even if it is
-  ;; available in the JSON output.
-  (insert (notmuch-show-get-bodypart-internal message-id nth))
-  (let ((file (read-file-name
-  "Filename to save as: "
-  (or mailcap-download-directory "~/")
-  nil nil
-  filename)))
-   ;; Don't re-compress .gz & al.  Arguably we should make
-   ;; `file-name-handler-alist' nil, but that would chop
-   ;; ange-ftp, which is reasonable to use here.
-   (mm-write-region (point-min) (point-max) file nil nil nil 
'no-conversion t)
+(defmacro notmuch-with-temp-part-buffer (message-id nth  body)
+  (declare (indent 2))
+  (let ((process-crypto (make-symbol "process-crypto")))
+`(let ((,process-crypto notmuch-show-process-crypto))
+   (with-temp-buffer
+(setq notmuch-show-process-crypto ,process-crypto)
+;; Always acquires the part via `notmuch part', even if it is
+;; available in the JSON output.
+(insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
+, at body
+
+(defun notmuch-show-save-part (message-id nth  filename content-type)
+  (notmuch-with-temp-part-buffer message-id nth
+(let ((file (read-file-name
+"Filename to save as: "
+(or mailcap-download-directory "~/")
+nil nil
+filename)))
+  ;; Don't re-compress .gz & al.  Arguably we should make
+  ;; `file-name-handler-alist' nil, but that would chop
+  ;; ange-ftp, which is reasonable to use here.
+  (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion 
t
+
+(defun notmuch-show-view-part (message-id nth  filename content-type )
+  (notmuch-with-temp-part-buffer message-id nth
+;; set mm-inlined-types to nil to force an external viewer
+(let ((handle (mm-make-handle (current-buffer) (list content-type)))
+ (mm-inlined-types nil))
+  (mm-display-part handle t
+
+(defun notmuch-show-interactively-view-part (message-id nth  filename 
content-type)
+  (notmuch-with-temp-part-buffer message-id nth
+(let ((handle (mm-make-handle (current-buffer) (list content-type
+  (mm-interactively-view-part handle

 (defun notmuch-show-mm-display-part-inline (msg part nth content-type)
   "Use the mm-decode/mm-view functions to display a part in the
@@ -1502,12 +1532,40 @@ buffer."

 ;; Commands typically bound to buttons.

-(defun notmuch-show-part-button-action (button)
-  (let ((nth 

Infinite loop in emacs interface

2012-01-17 Thread Rodney Lorrimar
Hi,

Actually, this is starting to look like a problem with gnus in the
latest emacs-snapshot.

I didn't notice before, but when I view the thread, I get this error:

Debugger entered--Lisp error: (void-variable gnus-inhibit-images)
  mm-shr((# ("text/html") nil nil nil nil nil nil))
  mm-inline-text-html((# ("text/html") nil nil nil nil nil nil))
  mm-display-inline((# ("text/html") nil nil nil nil nil nil))
  mm-display-part((# ("text/html") nil nil nil nil nil nil))
  notmuch-show-mm-display-part-inline(...snipped...)
  notmuch-search-show-thread(nil)
  call-interactively(notmuch-search-show-thread nil nil)

Someone seems to have come across it quite a while ago.

http://lists.gnu.org/archive/html/emacs-devel/2010-11/msg00625.html

This is quite strange because the previous emacs snapshot (20120105) was
working OK.

Running this code before viewing the thread seems to remove the error
and stop the infinite loop:

(defvar gnus-inhibit-images nil "*testing")
(set-variable 'gnus-inhibit-images nil)

But that's about the extent of my elisp knowledge. I'm not sure how to
actually fix the bug.


Cheers,

Rodney


[PATCH 1/1] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters
> 
> Oops, actually there was a bug in that macro.  It should have been
> 
> (defmacro notmuch-with-temp-part-buffer (message-id nth  body)
>   (declare (indent 2))
>   (let ((process-crypto (make-symbol "process-crypto")))
> `(let ((,process-crypto notmuch-show-process-crypto))
>(with-temp-buffer
>  (setq notmuch-show-process-crypto ,process-crypto)
>  ;; Always acquires the part via `notmuch part', even if it is
>  ;; available in the JSON output.
>  (insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
>  , at body
> 
> The only difference is on the "insert" line.  Sorry about that.

Fixed.

[Snip excellent explanation of defmacro]

Thanks for the excellent explanation!

> > Finally, I have discovered one bug/misfeature. If you try to "view" an
> > attachment then it will offer to save it but will not offer a
> > filename. If you try and save it (or use the default action) it will
> > offer a filename as now. As far as I can see this is not fixable if I
> > use mm-display-part: however, I could include a slight tweaked version,
> > notmuch-show-mm-display-part say, which would fix this corner
> > case. (Essentially, it would call notmuch-show-save-part if it failed to
> > find a handler rather than mailcap-save-binary-file.) However, this is
> > about 50 lines of lisp so I am not sure it is worth it.
> 
> Hmm.  This is probably worth fixing, but probably in a separate patch.
> Duplicating mm-display-part is probably not the way to go.  It think
> it will work to pass t as the no-default argument to mm-display-part
> and check the return value, which should be 'inline if it was able to
> handle it internally or 'external if it found an external helper.  I'm
> pretty sure it will never fall in to mailcap-save-binary-file in that
> case.  If that doesn't work, you could flet mailcap-save-binary-file
> around the call to mm-display-part.

I had tried passing t to mm-display-part and that didn't work as I
expected. I will experiment some more and try your flet suggestion but I
think that will be a separate patch.

I will send a potential final version of this patch as a reply to this
email. Many thanks for all the guidance and help!

Best wishes

Mark



[PATCH 1/4] emacs: unify search mechanisms

2012-01-17 Thread Dmitry Kurochkin
Hello.

On Mon, 16 Jan 2012 12:21:20 +, Jani Nikula  wrote:
> On Mon, 16 Jan 2012 15:39:14 +0400, Dmitry Kurochkin  gmail.com> wrote:
> > On Mon, 16 Jan 2012 11:35:37 +, David Edmondson  wrote:
> > > On Sun, 25 Dec 2011 08:14:52 +0400, Dmitry Kurochkin  > > gmail.com> wrote:
> > > > Before the change, there were two ways to do search in Emacs UI:
> > > > search widget in notmuch-hello buffer and `notmuch-search'
> > > > function bound to "s".  Internally, notmuch-hello search widget
> > > > uses `notmuch-search' function.  But it uses widget field input
> > > > instead of minibuffer.  Such duplication is a major issue for
> > > > notmuch-hello usability: search interface is inconsistent and
> > > > lacks features that are available in minibuffer (e.g. history and
> > > > auto completion).  Some of these features may be relatively easy
> > > > to implement for notmuch-hello search, others would be much more
> > > > tricky.  So to avoid duplication, make UI more consistent, bring
> > > > notmuch-hello search to feature parity with the minibuffer
> > > > search, the patch replaces notmuch-hello search widget and with a
> > > > button that works the same way as "s" key binding.
> > > 
> > > Dmitry, if Daniel re-submits his patches to allow the construction of
> > > `notmuch-hello' buffers to be configured, it seems that this patchset
> > > would become unnecessary. Is that correct?
> > 
> > Right.  We will just need to fix the 's' key binding.  Looking forward
> > for that.
> 
> Isn't (something like) this still needed to merge the search histories:
> 
> id:"1324698436-8532-1-git-send-email-dmitry.kurochkin at gmail.com"
> 

I have sent a new patch series implementing the changes [1].

Regards,
  Dmitry

[1] id:1326828850-8519-1-git-send-email-dmitry.kurochkin at gmail.com

> 
> Jani.


[PATCH 3/3] emacs: bind "s" to `notmuch-hello-search' in notmuch-hello buffer

2012-01-17 Thread Dmitry Kurochkin
`notmuch-hello-search' uses `notmuch-search' function but refreshes
notmuch-hello buffer when the search buffer is closed.
---
 emacs/notmuch-hello.el |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index cb36977..e908659 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -163,7 +163,8 @@ International Bureau of Weights and Measures."
  (format "%s%03d" notmuch-hello-thousands-separator elem))
 (cdr result)

-(defun notmuch-hello-search (search)
+(defun notmuch-hello-search ( search)
+  (interactive)
   (notmuch-search search notmuch-search-oldest-first nil nil
  #'notmuch-hello-search-continuation))

@@ -330,7 +331,7 @@ should be. Returns a cons cell `(tags-per-line width)'."
 (define-key map "G" 'notmuch-hello-poll-and-update)
 (define-key map (kbd "") 'widget-backward)
 (define-key map "m" 'notmuch-mua-new-mail)
-(define-key map "s" 'notmuch-search)
+(define-key map "s" 'notmuch-hello-search)
 map)
   "Keymap for \"notmuch hello\" buffers.")
 (fset 'notmuch-hello-mode-map notmuch-hello-mode-map)
-- 
1.7.8.3



[PATCH 2/3] emacs: use a single history for all searches

2012-01-17 Thread Dmitry Kurochkin
There are two ways to do search in Emacs UI: search widget in
notmuch-hello buffer and `notmuch-search' function bound to "s".
Before the change, these search mechanisms used different history
lists.  The patch makes notmuch-hello search use the same history list
as `notmuch-search' function.
---
 emacs/notmuch-hello.el |   49 ++--
 emacs/notmuch-lib.el   |9 
 emacs/notmuch.el   |   19 +--
 test/emacs.expected-output/notmuch-hello   |2 +-
 .../notmuch-hello-no-saved-searches|2 +-
 .../emacs.expected-output/notmuch-hello-with-empty |2 +-
 6 files changed, 40 insertions(+), 43 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 08fcd22..cb36977 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -29,8 +29,8 @@
 (declare-function notmuch-search "notmuch" (query  oldest-first 
target-thread target-line continuation))
 (declare-function notmuch-poll "notmuch" ())

-(defcustom notmuch-recent-searches-max 10
-  "The number of recent searches to store and display."
+(defcustom notmuch-hello-recent-searches-max 10
+  "The number of recent searches to display."
   :type 'integer
   :group 'notmuch)

@@ -151,16 +151,6 @@ International Bureau of Weights and Measures."
 (defvar notmuch-hello-url "http://notmuchmail.org;
   "The `notmuch' web site.")

-(defvar notmuch-hello-recent-searches nil)
-
-(defun notmuch-hello-remember-search (search)
-  (setq notmuch-hello-recent-searches
-   (delete search notmuch-hello-recent-searches))
-  (push search notmuch-hello-recent-searches)
-  (if (> (length notmuch-hello-recent-searches)
-notmuch-recent-searches-max)
-  (setq notmuch-hello-recent-searches (butlast 
notmuch-hello-recent-searches
-
 (defun notmuch-hello-nice-number (n)
   (let (result)
 (while (> n 0)
@@ -173,16 +163,9 @@ International Bureau of Weights and Measures."
  (format "%s%03d" notmuch-hello-thousands-separator elem))
 (cdr result)

-(defun notmuch-hello-trim (search)
-  "Trim whitespace."
-  (if (string-match "^[[:space:]]*\\(.*[^[:space:]]\\)[[:space:]]*$" search)
-  (match-string 1 search)
-search))
-
 (defun notmuch-hello-search (search)
-  (let ((search (notmuch-hello-trim search)))
-(notmuch-hello-remember-search search)
-(notmuch-search search notmuch-search-oldest-first nil nil 
#'notmuch-hello-search-continuation)))
+  (notmuch-search search notmuch-search-oldest-first nil nil
+ #'notmuch-hello-search-continuation))

 (defun notmuch-hello-add-saved-search (widget)
   (interactive)
@@ -461,7 +444,7 @@ Complete list of currently available key bindings:

 (let ((found-target-pos nil)
  (final-target-pos nil)
- (search-bar-pos))
+ (default-pos))
   (let* ((saved-alist
  ;; Filter out empty saved searches if required.
  (if notmuch-show-empty-saved-searches
@@ -493,7 +476,7 @@ Complete list of currently available key bindings:
(indent-rigidly start (point) notmuch-hello-indent)))

(widget-insert "\nSearch: ")
-   (setq search-bar-pos (point-marker))
+   (setq default-pos (point-marker))
(widget-create 'editable-field
   ;; Leave some space at the start and end of the
   ;; search boxes.
@@ -507,18 +490,18 @@ Complete list of currently available key bindings:
(put-text-property (1- (point)) (point) 'invisible t)
(widget-insert "\n")

-   (when notmuch-hello-recent-searches
+   (when notmuch-search-history
  (widget-insert "\nRecent searches: ")
  (widget-create 'push-button
 :notify (lambda ( ignore)
-  (setq notmuch-hello-recent-searches nil)
+  (setq notmuch-search-history nil)
   (notmuch-hello-update))
 "clear")
  (widget-insert "\n\n")
- (let ((start (point))
-   (nth 0))
-   (mapc (lambda (search)
-   (let ((widget-symbol (intern (format 
"notmuch-hello-search-%d" nth
+ (let ((start (point)))
+   (loop for i from 1 to notmuch-hello-recent-searches-max
+ for search in notmuch-search-history do
+   (let ((widget-symbol (intern (format 
"notmuch-hello-search-%d" i
  (set widget-symbol
   (widget-create 'editable-field
  ;; Don't let the search boxes be
@@ -545,9 +528,7 @@ Complete list of currently available key bindings:
   (notmuch-hello-add-saved-search 
widget))
 :notmuch-saved-search-widget widget-symbol
 

[PATCH 1/3] emacs: bind "s" to `notmuch-search' in notmuch-hello buffer

2012-01-17 Thread Dmitry Kurochkin
Before the change, "s" in notmuch-hello buffer would jump to the
search box.  The patch changes the binding to `notmuch-search' which
is consistent with all other notmuch buffers.
---
 emacs/notmuch-hello.el |   19 ++-
 1 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 02017ce..08fcd22 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -29,9 +29,6 @@
 (declare-function notmuch-search "notmuch" (query  oldest-first 
target-thread target-line continuation))
 (declare-function notmuch-poll "notmuch" ())

-(defvar notmuch-hello-search-bar-marker nil
-  "The position of the search bar within the notmuch-hello buffer.")
-
 (defcustom notmuch-recent-searches-max 10
   "The number of recent searches to store and display."
   :type 'integer
@@ -321,11 +318,6 @@ should be. Returns a cons cell `(tags-per-line width)'."
(widget-insert "\n"))
 found-target-pos))

-(defun notmuch-hello-goto-search ()
-  "Put point inside the `search' widget."
-  (interactive)
-  (goto-char notmuch-hello-search-bar-marker))
-
 (defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))

 (defun notmuch-hello-search-continuation()
@@ -355,7 +347,7 @@ should be. Returns a cons cell `(tags-per-line width)'."
 (define-key map "G" 'notmuch-hello-poll-and-update)
 (define-key map (kbd "") 'widget-backward)
 (define-key map "m" 'notmuch-mua-new-mail)
-(define-key map "s" 'notmuch-hello-goto-search)
+(define-key map "s" 'notmuch-search)
 map)
   "Keymap for \"notmuch hello\" buffers.")
 (fset 'notmuch-hello-mode-map notmuch-hello-mode-map)
@@ -468,7 +460,8 @@ Complete list of currently available key bindings:
   (widget-insert " messages.\n"))

 (let ((found-target-pos nil)
- (final-target-pos nil))
+ (final-target-pos nil)
+ (search-bar-pos))
   (let* ((saved-alist
  ;; Filter out empty saved searches if required.
  (if notmuch-show-empty-saved-searches
@@ -500,7 +493,7 @@ Complete list of currently available key bindings:
(indent-rigidly start (point) notmuch-hello-indent)))

(widget-insert "\nSearch: ")
-   (setq notmuch-hello-search-bar-marker (point-marker))
+   (setq search-bar-pos (point-marker))
(widget-create 'editable-field
   ;; Leave some space at the start and end of the
   ;; search boxes.
@@ -589,7 +582,7 @@ Complete list of currently available key bindings:
(when notmuch-saved-searches
  (widget-insert "Edit saved searches with the `edit' button.\n"))
(widget-insert "Hit RET or click on a saved search or tag name to view 
matching threads.\n")
-   (widget-insert "`=' refreshes this screen. `s' jumps to the search box. 
`q' to quit.\n")
+   (widget-insert "`=' refreshes this screen. `s' to search messages. `q' 
to quit.\n")
(let ((fill-column (- (window-width) notmuch-hello-indent)))
  (center-region start (point

@@ -601,7 +594,7 @@ Complete list of currently available key bindings:
  (widget-forward 1)))

   (unless (widget-at)
-   (notmuch-hello-goto-search
+   (goto-char search-bar-pos

   (run-hooks 'notmuch-hello-refresh-hook))

-- 
1.7.8.3



on deleting messages

2012-01-17 Thread Xavier Maillard
Hi,

On Tue, 17 Jan 2012 11:01:45 -0800, Jameson Graef Rollins  wrote:

[ ... ]

> Based on the show-mode improvements I recently sent [1], the following
> patch set implements thread and message delete keys.
> 
> This is the last I'm going to comment on this issue.  If we don't want
> to support this, we should put together something on the wiki that
> states we don't want to support it and that users should just bind it
> themselves (with a nice explanation how), so that we can try to reduce
> the number of future patches on the issue.

I think this is something every (new) users are expecting to have: a
simple and sensible way "to list the trashed messages". So I'd go for
it.

/Xavier


[PATCH 1/3] emacs: bind "s" to `notmuch-search' in notmuch-hello buffer

2012-01-17 Thread Jani Nikula
On Tue, 17 Jan 2012 23:34:08 +0400, Dmitry Kurochkin  wrote:
> Before the change, "s" in notmuch-hello buffer would jump to the
> search box.  The patch changes the binding to `notmuch-search' which
> is consistent with all other notmuch buffers.
> ---
>  emacs/notmuch-hello.el |   19 ++-
>  1 files changed, 6 insertions(+), 13 deletions(-)
> 
> diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
> index 02017ce..08fcd22 100644
> --- a/emacs/notmuch-hello.el
> +++ b/emacs/notmuch-hello.el
> @@ -29,9 +29,6 @@
>  (declare-function notmuch-search "notmuch" (query  oldest-first 
> target-thread target-line continuation))
>  (declare-function notmuch-poll "notmuch" ())
>  
> -(defvar notmuch-hello-search-bar-marker nil
> -  "The position of the search bar within the notmuch-hello buffer.")
> -
>  (defcustom notmuch-recent-searches-max 10
>"The number of recent searches to store and display."
>:type 'integer
> @@ -321,11 +318,6 @@ should be. Returns a cons cell `(tags-per-line width)'."
>   (widget-insert "\n"))
>  found-target-pos))
>  
> -(defun notmuch-hello-goto-search ()
> -  "Put point inside the `search' widget."
> -  (interactive)
> -  (goto-char notmuch-hello-search-bar-marker))

After this, what would the user have to do to bind some key to put the
point in the search box? If someone wants to restore old behaviour for
themselves.

Also, it's perhaps out of scope for this patch, but it will become more
evident now that notmuch-search does not respect
notmuch-search-oldest-first when called without parameters like the new
's' keybinding does. This is the same in search view.


BR,
Jani.


> -
>  (defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))
>  
>  (defun notmuch-hello-search-continuation()
> @@ -355,7 +347,7 @@ should be. Returns a cons cell `(tags-per-line width)'."
>  (define-key map "G" 'notmuch-hello-poll-and-update)
>  (define-key map (kbd "") 'widget-backward)
>  (define-key map "m" 'notmuch-mua-new-mail)
> -(define-key map "s" 'notmuch-hello-goto-search)
> +(define-key map "s" 'notmuch-search)
>  map)
>"Keymap for \"notmuch hello\" buffers.")
>  (fset 'notmuch-hello-mode-map notmuch-hello-mode-map)
> @@ -468,7 +460,8 @@ Complete list of currently available key bindings:
>(widget-insert " messages.\n"))
>  
>  (let ((found-target-pos nil)
> -   (final-target-pos nil))
> +   (final-target-pos nil)
> +   (search-bar-pos))
>(let* ((saved-alist
> ;; Filter out empty saved searches if required.
> (if notmuch-show-empty-saved-searches
> @@ -500,7 +493,7 @@ Complete list of currently available key bindings:
>   (indent-rigidly start (point) notmuch-hello-indent)))
>  
>   (widget-insert "\nSearch: ")
> - (setq notmuch-hello-search-bar-marker (point-marker))
> + (setq search-bar-pos (point-marker))
>   (widget-create 'editable-field
>  ;; Leave some space at the start and end of the
>  ;; search boxes.
> @@ -589,7 +582,7 @@ Complete list of currently available key bindings:
>   (when notmuch-saved-searches
> (widget-insert "Edit saved searches with the `edit' button.\n"))
>   (widget-insert "Hit RET or click on a saved search or tag name to view 
> matching threads.\n")
> - (widget-insert "`=' refreshes this screen. `s' jumps to the search box. 
> `q' to quit.\n")
> + (widget-insert "`=' refreshes this screen. `s' to search messages. `q' 
> to quit.\n")
>   (let ((fill-column (- (window-width) notmuch-hello-indent)))
> (center-region start (point
>  
> @@ -601,7 +594,7 @@ Complete list of currently available key bindings:
> (widget-forward 1)))
>  
>(unless (widget-at)
> - (notmuch-hello-goto-search
> + (goto-char search-bar-pos
>  
>(run-hooks 'notmuch-hello-refresh-hook))
>  
> -- 
> 1.7.8.3
> 
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/1] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters

> In general, yes, I think so.  A few comments on your draft below.

Ok I include a newer version which I am fairly happy with but I do have
some queries.

> > +(defvar notmuch-show-part-button-map
> > +  (let ((map (make-sparse-keymap)))
> > +   (set-keymap-parent map button-map)
> > +   (define-key map "s" 'notmuch-show-part-button-save)
> > +   (define-key map "v" 'notmuch-show-part-button-view)
> > +   (define-key map "o" 'notmuch-show-part-button-interactively-view)
> > +map)
> > +  "Submap for button commands")
> > +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
> 
> I don't think this fset is necessary.  Actually, I've never seen this
> outside of the notmuch code.  It looks like it does appear in code
> shipped with Emacs, but only in a handful of places.  All of those
> places look like very old code, so maybe this was necessary once upon
> a time?

I have no idea on this: at the moment I have left it in as fset for
keymaps seems to occur throughout notmuch (I have the fset because I
copied it from somewhere).

> (defmacro notmuch-with-temp-part-buffer (message-id nth  body)
>   (declare (indent 2))
>   (let ((process-crypto (make-symbol "process-crypto")))
> `(let ((,process-crypto notmuch-show-process-crypto))
>(with-temp-buffer
>  (setq notmuch-show-process-crypto ,process-crypto)
>  ;; Always acquires the part via `notmuch part', even if it is
>  ;; available in the JSON output.
>  (insert (notmuch-show-get-bodypart-internal message-id nth))
>  , at body

I have followed the macro approach: since notmuch-show-save-part also
uses it (which doesn't appear in the diff as it was unchanged). I have
made all three functions use notmuch-with-temp-part-buffer. However, I
used the macro exactly as you wrote it (and it seems to work) but I
moderately understand why but could not justify it to someone! 

> (defun notmuch-show-interactively-view-part (message-id nth content-type)
>   (notmuch-with-temp-part-buffer message-id nth
> (let ((handle (mm-make-handle (current-buffer) (list content-type
>   (mm-interactively-view-part handle)

Emacs wants to indent the (let line level with message-id in the line
above which looks odd (and makes the lines too long). Do I overrule
emacs, or put message-id and nth onto a separate line or is there
something better?

Also note that, because of the unification with notmuch-show-save-part
all three functions have to have the four arguments message-id, nth,
filename and content-type (even though currently each individual
function only uses three of them). However see below for another comment
on this.

> > +(defcustom notmuch-show-part-button-default-action 
> > 'notmuch-show-part-button-save
> > +  "Default part header button action (on ENTER or mouse click)."
> > +  :group 'notmuch
> > +  :type '(choice (const :tag "Save part"
> > +   notmuch-show-part-button-save)
> > +(const :tag "View part"
> > +   notmuch-show-part-button-view)
> > +(const :tag "View interactively"
> > +   notmuch-show-part-button-interactively-view)))
> 
> You probably want this to be the handler function, rather than the
> button function, since the interface to the button function is rather
> awkward.  That is, if someone wanted to plug in their own action, they
> would want to define it in terms of the high-level handler interface
> that you use above, rather than the low-level
> button-with-magic-properties interface that Emacs forces you to use
> below.

I have done this.

> This duplication is much worse, but also less necessary.
> 
> (defun notmuch-show-part-button-interactively-view ( button)
>   (interactive)
>   (notmuch-show-part-button-internal button 
> #'notmuch-show-interactively-view-part))
> 
> (defun notmuch-show-part-button-internal (button handler)
>   (let ((button (or button (button-at (point)
> (if button
>   (let ((nth (button-get button :notmuch-part)))
> (if nth
> (funcall handler (notmuch-show-get-message-id) nth
>  (button-get button :notmuch-content-type))
>   (message "Not a valid part (is it a fake part?)."))

Yes this is much nicer and I have done this too (modulo the extra
argument mentioned above).

Finally, I have discovered one bug/misfeature. If you try to "view" an
attachment then it will offer to save it but will not offer a
filename. If you try and save it (or use the default action) it will
offer a filename as now. As far as I can see this is not fixable if I
use mm-display-part: however, I could include a slight tweaked version,
notmuch-show-mm-display-part say, which would fix this corner
case. (Essentially, it would call notmuch-show-save-part if it failed to
find a handler rather than mailcap-save-binary-file.) However, this is
about 50 lines of lisp so I am not sure it is worth it.

Best wishes

Mark

on deleting messages

2012-01-17 Thread Jani Nikula
On Tue, 17 Jan 2012 11:01:45 -0800, Jameson Graef Rollins  wrote:
> Now that Austin's excellent tag exclusion patch set [0] has been pushed,
> the question remains if we want to support any delete-handling key
> bindings in emacs.
> 
> Based on the show-mode improvements I recently sent [1], the following
> patch set implements thread and message delete keys.
> 
> This is the last I'm going to comment on this issue.  If we don't want
> to support this, we should put together something on the wiki that
> states we don't want to support it and that users should just bind it
> themselves (with a nice explanation how), so that we can try to reduce
> the number of future patches on the issue.
> 
> Given the number of patches we've had on this issue, though, it's clear
> that a lot of people expect this functionality, so we may want to
> seriously consider supporting it.  Given Austin's tag exclusion stuff,
> and the fact that "deleted" tags are excluded by default, we now have
> the functionality that Carl originally wanted to see, so it's not so
> unreasonable to support this functionality anymore.

I think it's reasonable to consider having key bindings (or other
special handling) for pretty much *any* tags that are special to
notmuch: inbox, unread, draft, flagged, etc. (An exhaustive list should
be documented somewhere.)

Looking at the source and history, I have to admit there has been
intent, and code, to have support for "deleted" tag. See for example
TODO or [1].

And I agree there has been demand for this.

I say let's have this.

But make it clear that "deleted" is just a tag; that the messages aren't
going away, not by notmuch anyway.


BR,
Jani.

[1] commit 2c262042ac174d7bc96d6035ab9c88bd0abe7f35


[PATCH 1/1] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters

> > I am happy to make that change. My original patch in the summer was more
> > like that:
> > id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com"
> 
> Is this the right id?  I couldn't find it in the list archive.

Sorry I messed up: it should be id:"87mxehqhbl.fsf at r102.config" However
I have included my current draft along these lines. I think it is
working but I am not submitting yet: just asking if this is the right
idea.

Best wishes 

Mark

>From 9e52414b9871369c1cbb5c3e72d833b56bb236d4 Mon Sep 17 00:00:00 2001
From: Mark Walters 
Date: Sat, 14 Jan 2012 18:04:22 +
Subject: [PATCH] Make buttons for attachments allow viewing as well as saving

Define a keymap for attachment buttons to allow multiple actions.
Define 3 possible actions:
save attachment: exactly as currently,
view attachment: uses mailcap entry,
view attachment with user chosen program

Keymap on a button is: s for save, v for view and o for view with
other program. Default (i.e. enter or mouse button) is save but this
is configurable in notmuch customize.

One implementation detail: the view attachment function forces all
attachments to be "displayed" using mailcap even if emacs could
display them itself. Thus, for example, text/html appears in a browser
and text/plain asks whether to save (on a standard debian setup)
---
 emacs/notmuch-show.el |   87 
 1 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 03c1f6b..2413caa 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -281,10 +281,21 @@ message at DEPTH in the current thread."
(run-hooks 'notmuch-show-markup-headers-hook)

 (define-button-type 'notmuch-show-part-button-type
-  'action 'notmuch-show-part-button-action
+  'action 'notmuch-show-part-button-default
+  'keymap 'notmuch-show-part-button-map
   'follow-link t
   'face 'message-mml)

+(defvar notmuch-show-part-button-map
+  (let ((map (make-sparse-keymap)))
+   (set-keymap-parent map button-map)
+   (define-key map "s" 'notmuch-show-part-button-save)
+   (define-key map "v" 'notmuch-show-part-button-view)
+   (define-key map "o" 'notmuch-show-part-button-interactively-view)
+map)
+  "Submap for button commands")
+(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
+
 (defun notmuch-show-insert-part-header (nth content-type declared-type 
 name comment)
   (let ((button))
 (setq button
@@ -299,7 +310,8 @@ message at DEPTH in the current thread."
   " ]")
   :type 'notmuch-show-part-button-type
   :notmuch-part nth
-  :notmuch-filename name))
+  :notmuch-filename name
+  :notmuch-content-type content-type))
 (insert "\n")
 ;; return button
 button))
@@ -323,6 +335,28 @@ message at DEPTH in the current thread."
;; ange-ftp, which is reasonable to use here.
(mm-write-region (point-min) (point-max) file nil nil nil 
'no-conversion t)

+(defun notmuch-show-view-part (message-id nth content-type)
+  (let ((process-crypto notmuch-show-process-crypto))
+(with-temp-buffer
+  (setq notmuch-show-process-crypto process-crypto)
+  ;; Always acquires the part via `notmuch part', even if it is
+  ;; available in the JSON output.
+  (insert (notmuch-show-get-bodypart-internal message-id nth))
+  ;; set mm-inlined-types to nil to force an external viewer
+  (let ((handle (mm-make-handle (current-buffer) (list content-type)))
+   (mm-inlined-types nil))
+   (mm-display-part handle t)
+
+(defun notmuch-show-interactively-view-part (message-id nth content-type)
+  (let ((process-crypto notmuch-show-process-crypto))
+(with-temp-buffer
+  (setq notmuch-show-process-crypto process-crypto)
+  ;; Always acquires the part via `notmuch part', even if it is
+  ;; available in the JSON output.
+  (insert (notmuch-show-get-bodypart-internal message-id nth))
+  (let ((handle (mm-make-handle (current-buffer) (list content-type
+   (mm-interactively-view-part handle)
+
 (defun notmuch-show-mm-display-part-inline (msg part nth content-type)
   "Use the mm-decode/mm-view functions to display a part in the
 current buffer, if possible."
@@ -1502,12 +1536,49 @@ buffer."

 ;; Commands typically bound to buttons.

-(defun notmuch-show-part-button-action (button)
-  (let ((nth (button-get button :notmuch-part)))
-(if nth
-   (notmuch-show-save-part (notmuch-show-get-message-id) nth
-   (button-get button :notmuch-filename))
-  (message "Not a valid part (is it a fake part?)."
+(defcustom notmuch-show-part-button-default-action 
'notmuch-show-part-button-save
+  "Default part header button action (on ENTER or mouse click)."
+  :group 'notmuch
+  :type '(choice (const :tag "Save part"
+   

[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Austin Clements
Quoth Mark Walters on Jan 18 at 12:40 am:
> 
> > Oof, sorry.  Two more tweaks that I really should have caught in the
> > previous version.  After that this gets my automatic +1.
> 
> Both fixed. I have also fixed the bug I mentioned (missing filename when
> "view" falls back on save); I couldn't make it work with the
> "no-default" option. However overriding mm-save-part with flet seems to
> do the trick.

Oh, indeed.  I'd foolishly assumed that when mm-display-part passed
the function mailcap-save-binary-file as the method to
mm-display-external that it would actually *use* that function, but
you're right that it uses mm-save-part.

> +(defun notmuch-show-view-part (message-id nth  filename 
> content-type )
> +  (notmuch-with-temp-part-buffer message-id nth
> +;; set mm-inlined-types to nil to force an external viewer
> +(let ((handle (mm-make-handle (current-buffer) (list content-type)))
> + (mm-inlined-types nil))
> +  ;; We override mm-save-part as notmuch-show-save-part is better
> +  ;; since it offers the filename
> +  (flet ((mm-save-part ( args) (ignore)))
> +   (or (mm-display-part handle)
> +   (notmuch-show-save-part message-id nth filename 
> content-type))
> 
> Is that a reasonable solution? 

It's *probably* safe to depend on the result of mm-display-part, but
you can avoid the question altogether by simply calling
notmuch-show-save-part from your flet mm-save-part.  E.g.,

(flet ((mm-save-part ( args) (notmuch-show-save-part 
   message-id nth filename content-type)))
  (mm-display-part handle))

(Yeah, flet indentation is lame.)

> Best wishes
> 
> Mark


[PATCH] fix .gitignore for gzipped man pages

2012-01-17 Thread Jani Nikula
---
 .gitignore |1 -
 man/.gitignore |2 ++
 2 files changed, 2 insertions(+), 1 deletions(-)
 create mode 100644 man/.gitignore

diff --git a/.gitignore b/.gitignore
index d64ec9f..d428290 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,6 @@ tags
 /notmuch
 notmuch.sym
 notmuch-shared
-notmuch.1.gz
 libnotmuch.so*
 libnotmuch*.dylib
 *.[ao]
diff --git a/man/.gitignore b/man/.gitignore
new file mode 100644
index 000..26ead20
--- /dev/null
+++ b/man/.gitignore
@@ -0,0 +1,2 @@
+# ignore gzipped man pages
+*.[0-9].gz
-- 
1.7.5.4



[PATCH v2] emacs: add invisible dot instead of space at the end of notmuch-hello search box

2012-01-17 Thread Dmitry Kurochkin
This makes `show-trailing-whitespace' happy, i.e. it does not mark the
whole search box line as trailing spaces.

Since the dot is invisible, this change makes no visible difference
for `notmuch-hello'.
---
 emacs/notmuch-hello.el |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 02017ce..38846ef 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -508,9 +508,12 @@ Complete list of currently available key bindings:
   (length "Search: ")))
   :action (lambda (widget  ignore)
 (notmuch-hello-search (widget-value widget
-   ;; add an invisible space to make `widget-end-of-line' ignore
-   ;; trailine spaces in the search widget field
-   (widget-insert " ")
+   ;; Add an invisible dot to make `widget-end-of-line' ignore
+   ;; trailing spaces in the search widget field.  A dot is used
+   ;; instead of a space to make `show-trailing-whitespace'
+   ;; happy, i.e. avoid it marking the whole line as trailing
+   ;; spaces.
+   (widget-insert ".")
(put-text-property (1- (point)) (point) 'invisible t)
(widget-insert "\n")

-- 
1.7.8.3



Partial words on notmuch search?

2012-01-17 Thread Jani Nikula
On Mon, 16 Jan 2012 21:34:31 -0500, Austin Clements  wrote:
> Quoth Andrei Popescu on Jan 16 at 10:21 pm:
> > This is also interesting:
> > $ notmuch count 'debian'
> > 65888
> > $ notmuch count 'dEbian'
> > 65888
> > $ notmuch count 'Debian'
> > 65887
> 
> The first two will match stemmed versions of "debian" such as
> "debian's" and "debianed".  However, starting a term with a capital
> letter suppresses stemming (because it suggests that it's a name,
> which you wouldn't want to modify), so your last query matches only
> the term "debian".  This is probably documented somewhere, though I
> don't know where.

Interesting. Is this done when adding the terms to the database, or when
searching? I presume the latter. How much control does notmuch have over
this?

The assumption that one wouldn't want to have stemming for names is very
much language dependent. [1]

BR,
Jani.


[1] http://en.wikipedia.org/wiki/Finnish_noun_cases (the same works for
names as well as nouns)


Infinite loop in emacs interface

2012-01-17 Thread Rodney Lorrimar
On Tue, 17 Jan 2012 12:37:52 -0500, Aaron Ecay  wrote:
> After converting the mbox file to Maildir and adding it to my mailstore,
> I cannot reproduce the loop.  (The versions of notmuch and emacs I used
> are close to the ones you have, but not an exact match, so it may be
> something subtle about those versions.  I can investigate
> more carefully if it seems like this is the case.)

Hi Aaron,

That's a pity. I am using Julien Danjou's emacs-snapshot package for
debian and actually I only noticed the infinite loop on this thread
after restarting emacs some unknown time after the package was
upgraded. The package was upgraded from 20120105 to 20120111.

I haven't been using this snapshot of emacs for very long, so possibly
the problem might occur with other threads. To test this thread, I
copied it out of my maildirs with mutt, deleted the original messages,
ran "notmuch new", copied the mbox thread back into my maildirs, then
ran "notmuch new" again, and the problem was still there.


> If you do:
> M-x set-variable RET debug-on-quit RET t RET
> then trigger the loop and press C-g, you should get a buffer showing a
> backtrace of the lisp stack.  What does that say?

I copied 4 backtraces which appear below. I pressed the 'a' key when
viewing the thread, then C-g.

They were run with notmuch git commit efa5d6cb32. Since then I went back
to 0.11 because it seems like the reply function stopped working.


Cheers,

Rodney


Debugger entered--Lisp error: (quit)
  mapc((lambda (del-tag) (setq result-tags (delete del-tag result-tags))) 
("inbox"))
  (let ((result-tags (copy-sequence current-tags))) (mapc (lambda (del-tag) 
(setq result-tags (delete del-tag result-tags))) del-tags) result-tags)
  notmuch-show-del-tags-worker(nil ("inbox"))
  (let* ((current-tags (notmuch-show-get-tags)) (new-tags 
(notmuch-show-del-tags-worker current-tags toremove))) (unless (equal 
current-tags new-tags) (apply (quote notmuch-tag) (notmuch-show-get-message-id) 
(mapcar (lambda (s) (concat "-" s)) toremove)) (notmuch-show-set-tags 
new-tags)))
  notmuch-show-remove-tag("inbox")
  (progn (notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next
  (while (progn (notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next)
  (catch (quote --cl-block-nil--) (while (progn (notmuch-show-remove-tag 
"inbox") (not (not (notmuch-show-goto-message-next) nil)
  (cl-block-wrapper (catch (quote --cl-block-nil--) (while (progn 
(notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next) nil))
  (block nil (while (progn (notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next) nil)
  (loop do (notmuch-show-remove-tag "inbox") until (not 
(notmuch-show-goto-message-next)))
  notmuch-show-archive-thread-internal(t)
  notmuch-show-archive-thread()
  call-interactively(notmuch-show-archive-thread nil nil)

Debugger entered--Lisp error: (quit)
  notmuch-show-move-to-message-top()
  (save-excursion (notmuch-show-move-to-message-top) (get-text-property (point) 
:notmuch-message-properties))
  notmuch-show-get-message-properties()
  (or props (notmuch-show-get-message-properties))
  (let ((props (or props (notmuch-show-get-message-properties (plist-get 
props prop))
  notmuch-show-get-prop(:tags)
  notmuch-show-get-tags()
  (let* ((current-tags (notmuch-show-get-tags)) (new-tags 
(notmuch-show-del-tags-worker current-tags toremove))) (unless (equal 
current-tags new-tags) (apply (quote notmuch-tag) (notmuch-show-get-message-id) 
(mapcar (lambda (s) (concat "-" s)) toremove)) (notmuch-show-set-tags 
new-tags)))
  notmuch-show-remove-tag("inbox")
  (progn (notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next
  (while (progn (notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next)
  (catch (quote --cl-block-nil--) (while (progn (notmuch-show-remove-tag 
"inbox") (not (not (notmuch-show-goto-message-next) nil)
  (cl-block-wrapper (catch (quote --cl-block-nil--) (while (progn 
(notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next) nil))
  (block nil (while (progn (notmuch-show-remove-tag "inbox") (not (not 
(notmuch-show-goto-message-next) nil)
  (loop do (notmuch-show-remove-tag "inbox") until (not 
(notmuch-show-goto-message-next)))
  notmuch-show-archive-thread-internal(t)
  notmuch-show-archive-thread()
  call-interactively(notmuch-show-archive-thread nil nil)

Debugger entered--Lisp error: (quit)
  notmuch-show-move-to-message-top()
  (save-excursion (notmuch-show-move-to-message-top) (get-text-property (point) 
:notmuch-message-properties))
  notmuch-show-get-message-properties()
  (or props (notmuch-show-get-message-properties))
  (let ((props (or props (notmuch-show-get-message-properties (plist-get 
props prop))
  notmuch-show-get-prop(:tags)
  notmuch-show-get-tags()
  (let* ((current-tags (notmuch-show-get-tags)) (new-tags 
(notmuch-show-del-tags-worker 

[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Austin Clements
Quoth Mark Walters on Jan 17 at 11:44 pm:
> Define a keymap for attachment buttons to allow multiple actions.
> Define 3 possible actions:
> save attachment: exactly as currently,
> view attachment: uses mailcap entry,
> view attachment with user chosen program
> 
> Keymap on a button is: s for save, v for view and o for view with
> other program. Default (i.e. enter or mouse button) is save but this
> is configurable in notmuch customize.
> 
> One implementation detail: the view attachment function forces all
> attachments to be "displayed" using mailcap even if emacs could
> display them itself. Thus, for example, text/html appears in a browser
> and text/plain asks whether to save (on a standard debian setup)

Oof, sorry.  Two more tweaks that I really should have caught in the
previous version.  After that this gets my automatic +1.

> ---
>  emacs/notmuch-show.el |  106 
> ++---
>  1 files changed, 82 insertions(+), 24 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 03c1f6b..0aaaf79 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -281,10 +281,21 @@ message at DEPTH in the current thread."
>   (run-hooks 'notmuch-show-markup-headers-hook)
>  
>  (define-button-type 'notmuch-show-part-button-type
> -  'action 'notmuch-show-part-button-action
> +  'action 'notmuch-show-part-button-default
> +  'keymap 'notmuch-show-part-button-map
>'follow-link t
>'face 'message-mml)
>  
> +(defvar notmuch-show-part-button-map
> +  (let ((map (make-sparse-keymap)))
> +   (set-keymap-parent map button-map)
> +   (define-key map "s" 'notmuch-show-part-button-save)
> +   (define-key map "v" 'notmuch-show-part-button-view)
> +   (define-key map "o" 'notmuch-show-part-button-interactively-view)

Indentation.

> +map)
> +  "Submap for button commands")
> +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
> +
>  (defun notmuch-show-insert-part-header (nth content-type declared-type 
>  name comment)
>(let ((button))
>  (setq button
> @@ -299,29 +310,48 @@ message at DEPTH in the current thread."
>  " ]")
>  :type 'notmuch-show-part-button-type
>  :notmuch-part nth
> -:notmuch-filename name))
> +:notmuch-filename name
> +:notmuch-content-type content-type))
>  (insert "\n")
>  ;; return button
>  button))
>  
>  ;; Functions handling particular MIME parts.
>  
> -(defun notmuch-show-save-part (message-id nth  filename)
> -  (let ((process-crypto notmuch-show-process-crypto))
> -(with-temp-buffer
> -  (setq notmuch-show-process-crypto process-crypto)
> -  ;; Always acquires the part via `notmuch part', even if it is
> -  ;; available in the JSON output.
> -  (insert (notmuch-show-get-bodypart-internal message-id nth))
> -  (let ((file (read-file-name
> -"Filename to save as: "
> -(or mailcap-download-directory "~/")
> -nil nil
> -filename)))
> - ;; Don't re-compress .gz & al.  Arguably we should make
> - ;; `file-name-handler-alist' nil, but that would chop
> - ;; ange-ftp, which is reasonable to use here.
> - (mm-write-region (point-min) (point-max) file nil nil nil 
> 'no-conversion t)
> +(defmacro notmuch-with-temp-part-buffer (message-id nth  body)
> +  (declare (indent 2))
> +  (let ((process-crypto (make-symbol "process-crypto")))
> +`(let ((,process-crypto notmuch-show-process-crypto))
> +   (with-temp-buffer
> +  (setq notmuch-show-process-crypto ,process-crypto)
> +  ;; Always acquires the part via `notmuch part', even if it is
> +  ;; available in the JSON output.
> +  (insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
> +  , at body
> +
> +(defun notmuch-show-save-part (message-id nth  filename 
> content-type)
> +  (notmuch-with-temp-part-buffer message-id nth
> +(let ((file (read-file-name
> +  "Filename to save as: "
> +  (or mailcap-download-directory "~/")
> +  nil nil
> +  filename)))
> +  ;; Don't re-compress .gz & al.  Arguably we should make
> +  ;; `file-name-handler-alist' nil, but that would chop
> +  ;; ange-ftp, which is reasonable to use here.
> +  (mm-write-region (point-min) (point-max) file nil nil nil 
> 'no-conversion t
> +
> +(defun notmuch-show-view-part (message-id nth  filename 
> content-type )
> +  (notmuch-with-temp-part-buffer message-id nth
> +;; set mm-inlined-types to nil to force an external viewer
> +(let ((handle (mm-make-handle (current-buffer) (list content-type)))
> +   (mm-inlined-types nil))
> +  (mm-display-part handle t
> +
> +(defun notmuch-show-interactively-view-part (message-id nth  
> filename content-type)
> +  (notmuch-with-temp-part-buffer message-id nth
> +(let ((handle (mm-make-handle 

[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.

2012-01-17 Thread Dmitry Kurochkin
On Tue, 17 Jan 2012 14:37:52 +, David Edmondson  wrote:
> (And for the list...)
> 
> On Tue, 17 Jan 2012 18:20:04 +0400, Dmitry Kurochkin  gmail.com> wrote:
> > Can you please elaborate why this is needed?
> 
> This code:
> 
>   # wait until the emacs server is up
>   until test_emacs '()' 2>/dev/null; do
>   sleep 1
>   done
> 
> outputs 'nil', so the first caller to test_emacs has 'nil\n' prepended
> to their expected output.

Thanks.  Would be nice to have this explained in the commit message.  No
need to resend just because of this though.

Regards,
  Dmitry


[PATCH 2/3] test: Add `test_emacs_expect_t'.

2012-01-17 Thread Dmitry Kurochkin
On Tue, 17 Jan 2012 14:35:07 +, David Edmondson  wrote:
> On Tue, 17 Jan 2012 18:26:41 +0400, Dmitry Kurochkin  gmail.com> wrote:
> > Sorry, I still do not understand why we can not implement
> > test_emacs_expect_t() like:
> > 
> >   result=${test_emacs $@}
> >   test_expect_equal $result t
> > 
> > Can you please explain?
> 
> In the failure case test_expect_equal does:
> 
>   test_failure_ "$test_subtest_name" "$(diff -u $testname.expected 
> $testname.output)"
> 
> that diff output is not useful here, because the test harness doesn't
> have any expected output other than `t' with which to diff the actual
> output.
> 
> The emacs-address-cleaning test shows how we will provide expected
> vs. actual output directly from within emacs, making it easier for the
> developer to figure out what went wrong.

Thanks for the explanation.

Regards,
  Dmitry


[PATCH 2/3] test: Add `test_emacs_expect_t'.

2012-01-17 Thread Dmitry Kurochkin
On Tue, 17 Jan 2012 14:07:03 +, David Edmondson  wrote:
> Add a new test function to allow simpler testing of emacs
> functionality.
> 
> `test_emacs_expect_t' takes one argument - a list expression to
> evaluate. The test passes if the expression returns `t', otherwise it
> fails and the output is reported to the tester.
> ---
> 
> Re-worked as Dmitry suggested.
> 
>  test/README  |8 
>  test/emacs-test-functions.sh |9 +
>  test/notmuch-test|1 +
>  test/test-lib.sh |   33 +
>  4 files changed, 51 insertions(+), 0 deletions(-)
>  create mode 100755 test/emacs-test-functions.sh
> 
> diff --git a/test/README b/test/README
> index bde6db0..9dbe2ee 100644
> --- a/test/README
> +++ b/test/README
> @@ -189,6 +189,14 @@ library for your script to use.
> tests that may run in the same Emacs instance.  Use `let' instead
> so the scope of the changed variables is limited to a single test.
>  
> + test_emacs_expect_t 
> +
> +  This function executes the provided emacs lisp script within
> +  emacs in a manner similar to 'test_emacs'. The expressions should
> +  return the value `t' to indicate that the test has passed. If the
> +  test does not return `t' then it is considered failed and all data
> +  returned by the test is reported to the tester.
> +
>   test_done
>  
> Your test script must have test_done at the end.  Its purpose
> diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh
> new file mode 100755
> index 000..0e1f9fc
> --- /dev/null
> +++ b/test/emacs-test-functions.sh
> @@ -0,0 +1,9 @@
> +#!/usr/bin/env bash
> +
> +test_description="emacs test function sanity"
> +. test-lib.sh
> +
> +test_begin_subtest "emacs test function sanity"
> +test_emacs_expect_t 't'
> +
> +test_done
> diff --git a/test/notmuch-test b/test/notmuch-test
> index 6a99ae3..d034f99 100755
> --- a/test/notmuch-test
> +++ b/test/notmuch-test
> @@ -52,6 +52,7 @@ TESTS="
>python
>hooks
>argument-parsing
> +  emacs-test-functions.sh
>  "
>  TESTS=${NOTMUCH_TESTS:=$TESTS}
>  
> diff --git a/test/test-lib.sh b/test/test-lib.sh
> index 7c9ce24..4b05760 100644
> --- a/test/test-lib.sh
> +++ b/test/test-lib.sh
> @@ -503,6 +503,39 @@ test_expect_equal_file ()
>  fi
>  }
>  
> +test_emacs_expect_t () {
> + test "$#" = 1 || error "bug in the test script: not 1 parameter to 
> test_emacs_expect_t"
> +
> + # Run the test.
> + if ! test_skip "$test_subtest_name"
> + then
> + # We cannot call 'test_emacs' in a subshell, because
> + # the setting of EMACS_SERVER would not persist
> + # throughout a sequence of tests, so we use a
> + # temporary file.
> + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi
> + output="$tmp/test_emacs_output.$$"
> + test_emacs "$1" > "${output}"
> + result=$(cat "${output}")
> + rm -f "${output}"
> + fi
> +
> + # Restore state after the test.
> + exec 1>&6 2>&7  # Restore stdout and stderr
> + inside_subtest=
> +
> + # Report success/failure.
> + if ! test_skip "$test_subtest_name"
> + then
> + if [ "$result" == t ]
> + then
> + test_ok_ "$test_subtest_name"
> + else
> + test_failure_ "$test_subtest_name" "$(eval printf 
> ${result})"
> + fi
> + fi
> +}
> +

Sorry, I still do not understand why we can not implement
test_emacs_expect_t() like:

  result=${test_emacs $@}
  test_expect_equal $result t

Can you please explain?

Regards,
  Dmitry

>  NOTMUCH_NEW ()
>  {
>  notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found 
> [0-9]* total file'
> -- 
> 1.7.7.3
> 
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Start devel directory for developer tools and documentation.

2012-01-17 Thread Austin Clements
Quoth David Bremner on Jan 17 at  8:47 am:
> From: David Bremner 
> 
> We had a lot of back and forth about the name of this directory, but
> nothing very conclusive. In the end, I just chose "devel" just to move
> on.

LGTM.


[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.

2012-01-17 Thread Dmitry Kurochkin
Can you please elaborate why this is needed?

Regards,
  Dmitry


Infinite loop in emacs interface

2012-01-17 Thread Rodney Lorrimar
Hi,

Emacs notmuch is a really excellent mail program.

But today I got an infinite loop in emacs 24.0.92.1 with notmuch (0.11
and master). It only happens when viewing a certain thread.

There seem to be 2 problems:

1. the n and p keys (notmuch-show-{next,previous}-open-message) can't
   get past the second message in the thread.

2. when using the 'a' key (notmuch-show-archive-thread), it will loop,
   probably because it can't get past the second message.

The thread is attached.

Cheers,

Rodney

-- next part --
A non-text attachment was scrubbed...
Name: loop-thread.gz
Type: application/octet-stream
Size: 6912 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/a28ae422/attachment.obj>


[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box

2012-01-17 Thread Dmitry Kurochkin
On Tue, 17 Jan 2012 14:08:58 +, David Edmondson  wrote:
> On Tue, 17 Jan 2012 17:24:45 +0400, Dmitry Kurochkin  gmail.com> wrote:
> > This makes `show-trailing-whitespace' happy, i.e. it does not mark the
> > whole search box line as trailing spaces.
> 
> Why should `whitespace-mode' be active in `notmuch-hello' buffers?

I do not say that it should be active in notmuch-hello.

For me `show-trailing-whitespace' is activated everywhere with some
exceptions.  Notmuch-hello is one of these exceptions.  This change make
it one step closer to removing the exception.

Regards,
  Dmitry


[PATCH 1/1] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Austin Clements
Quoth Mark Walters on Jan 17 at 10:27 pm:
> > (defmacro notmuch-with-temp-part-buffer (message-id nth  body)
> >   (declare (indent 2))
> >   (let ((process-crypto (make-symbol "process-crypto")))
> > `(let ((,process-crypto notmuch-show-process-crypto))
> >(with-temp-buffer
> >  (setq notmuch-show-process-crypto ,process-crypto)
> >  ;; Always acquires the part via `notmuch part', even if it is
> >  ;; available in the JSON output.
> >  (insert (notmuch-show-get-bodypart-internal message-id nth))
> >  , at body
> 
> I have followed the macro approach: since notmuch-show-save-part also
> uses it (which doesn't appear in the diff as it was unchanged). I have
> made all three functions use notmuch-with-temp-part-buffer. However, I
> used the macro exactly as you wrote it (and it seems to work) but I
> moderately understand why but could not justify it to someone! 

Oops, actually there was a bug in that macro.  It should have been

(defmacro notmuch-with-temp-part-buffer (message-id nth  body)
  (declare (indent 2))
  (let ((process-crypto (make-symbol "process-crypto")))
`(let ((,process-crypto notmuch-show-process-crypto))
   (with-temp-buffer
 (setq notmuch-show-process-crypto ,process-crypto)
 ;; Always acquires the part via `notmuch part', even if it is
 ;; available in the JSON output.
 (insert (notmuch-show-get-bodypart-internal ,message-id ,nth))
 , at body

The only difference is on the "insert" line.  Sorry about that.

I don't know how familiar you are with syntactic abstraction, so
here's a top-down explanation.  A macro is like the compile-time
equivalent of a function: rather than the arguments and return being
values that result from evaluation, they are pieces of code, the body
of the macro executes at compile time instead of at run time, and the
compiler replaces the invocation of the macro with the code that the
macro returns.  This is not unlike a C/C++ macro, but the
implementation of the macro is regular Lisp code that runs at compile
time and the code is represented as S-expressions rather than strings
(one beauty of Lisp is that the representation of code and data is the
same).

The above macro returns the code starting after the "`" (pronounced
quasiquote), so that's what invocations of the macro get replaced
with.  Quasiquote (like quote) inhibits the evaluation of what follows
it and results in the code as data, rather than the result of
evaluating the code.  Unlike quote, quasiquote lets you jump back into
the evaluator using "," and ",@", so it's great for piecing together
code from a template, which is what macros spend most of their time
doing.

The "declare" is simply a specification to emacs-lisp-mode about how
to indent uses of this macro.  The "make-symbol" is necessary to avoid
conflicting with variable names that may appear in the code that uses
this macro (since the invoking code and the code returned by the macro
will be interleaved, you have to worry about variable conflicts).

> > (defun notmuch-show-interactively-view-part (message-id nth content-type)
> >   (notmuch-with-temp-part-buffer message-id nth
> > (let ((handle (mm-make-handle (current-buffer) (list content-type
> >   (mm-interactively-view-part handle)
> 
> Emacs wants to indent the (let line level with message-id in the line
> above which looks odd (and makes the lines too long). Do I overrule
> emacs, or put message-id and nth onto a separate line or is there
> something better?

If you evaluate the defmacro, it'll pick up on that declare line at
the beginning of it and indent this correctly.

> Also note that, because of the unification with notmuch-show-save-part
> all three functions have to have the four arguments message-id, nth,
> filename and content-type (even though currently each individual
> function only uses three of them). However see below for another comment
> on this.

That makes sense.

> > > +(defcustom notmuch-show-part-button-default-action 
> > > 'notmuch-show-part-button-save
> > > +  "Default part header button action (on ENTER or mouse click)."
> > > +  :group 'notmuch
> > > +  :type '(choice (const :tag "Save part"
> > > + notmuch-show-part-button-save)
> > > +  (const :tag "View part"
> > > + notmuch-show-part-button-view)
> > > +  (const :tag "View interactively"
> > > + notmuch-show-part-button-interactively-view)))
> > 
> > You probably want this to be the handler function, rather than the
> > button function, since the interface to the button function is rather
> > awkward.  That is, if someone wanted to plug in their own action, they
> > would want to define it in terms of the high-level handler interface
> > that you use above, rather than the low-level
> > button-with-magic-properties interface that Emacs forces you to use
> > below.
> 
> I have done this.
> 
> > This duplication is 

[PATCH 1/2] uncrustify.cfg: initial support for notmuch coding style

2012-01-17 Thread Tomi Ollila
On Tue, 10 Jan 2012 08:07:07 -0400, David Bremner  wrote:
> From: David Bremner 
> 
> Uncrustify is a free (as in GPL2+) tool that indents and beautifies
> C/C++ code. It is similar to GNU indent in functionality although
> probably more configurable (in fairness, indent has better
> documentation).  Uncrustify does not have the indent mis-feature of
> needing to have every typedef'ed type defined in the
> configuration (even standard types like size_t).
> 
> This configuration starts with the linux-kernel style from the
> uncrustify config, disables aggressive re-indenting of structs,
> and fine tunes the handling 'else' and braces.
> 
> In an ideal situation, running uncrustify on notmuch code would be
> NOP; currently this is not true for all files because 1) the
> configuration is not perfect 2) the coding style of notmuch is not
> completely consistent; in particular the treatment of braces after
> e.g. for (_) is not consistent.
> ---
>  uncrustify.cfg |   99 
> 

Good stuff: while testing I did these changes:

--- uncrustify.cfg0 2012-01-17 16:20:18.686489325 +0200
+++ uncrustify.cfg  2012-01-17 17:02:39.664512588 +0200
@@ -21 +20,0 @@
-
@@ -60,0 +60,4 @@
+sp_before_ptr_star = force
+sp_between_ptr_star= remove
+sp_after_ptr_star  = remove
+
@@ -62 +65 @@
-sp_sizeof_paren= remove# "sizeof (int)" vs 
"sizeof(int)"
+sp_sizeof_paren= force # "sizeof (int)" vs 
"sizeof(int)"
@@ -93 +96 @@
-align_right_cmt_span   = 0
+align_right_cmt_span   = 1 # 0 -> 1 -- just to fix some alignments


The first three:

+sp_before_ptr_star = force
+sp_between_ptr_star= remove
+sp_after_ptr_star  = remove

are important and pretty uncontroversial; fixes more than breaks (if
anything)


+sp_sizeof_paren= force # "sizeof (int)" vs "sizeof(int)"

adds space after sizeof; do 'grep sizeof *.c' and you see this is
prevalent in the code. I think this is the right way (especially) as 
sizeof is an operator...


+align_right_cmt_span   = 1 # 0 -> 1 -- just to fix some alignments

This fixes, for example, comment alignment in g_mime_filter_headers_get_type()
(in gmime-filter-headers.c).


I also tested using this change:

@@ -66 +69 @@
-sp_after_cast  = force # "(int) a" vs "(int)a"
+sp_after_cast  = remove# "(int) a" vs "(int)a"

But this changes basically all the casts in code not to have space
after cast. I'd prefer this but it is not the prevalent style.

Note that just running 
uncrustify --replace -c uncrustify.cfg notmuch-show.c
does this:

format_part_start_json (unused (GMimeObject * part),

I.e. there is space after '*' and 'part'. This is probably
the old known problem: uncrustify thinks unused is function 
which takes int parameter and there is multiplication to be 
done. If there is way to tell uncrustify that GMimeObject is 
type then this change would not take place.


I run for f in *.c; do uncrustify --replace -c uncrustify.cfg $f; done

in notmuch source root directory and the output is pretty good, in addition
to the above problem there are these format_* structure initialization
changes: 
Quoting Austin: "The good news is that that structure is on its way out."

So, it would be good to get devel/uncrustify.cfg in place so developers
can start playing with it...

Tomi



Notmuch fails to build with gmime 2.6.4

2012-01-17 Thread Austin Clements
Quoth hollunder at lavabit.com on Jan 17 at  4:24 pm:
> Hi there. I've seen gmime related discussion but it's hard to follow using
> a web interface, so here's my bug report.

There's a GMime 2.6 support patch that will probably make it into the
master branch in the next day or two.  Sorry for the inconvenience.


Improving notmuch query documentation [was: Re: Partial words on notmuch search?]

2012-01-17 Thread Austin Clements
Quoth Andrei Popescu on Jan 18 at 12:14 am:
> On Lu, 16 ian 12, 21:34:31, Austin Clements wrote:
> > Quoth Andrei Popescu on Jan 16 at 10:21 pm:
> > > Where can I read more about this? (except the source :)
> > 
> > Most of this is in the Xapian query syntax document you found.  Really
> > we ought to beef-up Notmuch's query syntax documentation.
> 
> If I get around to write something myself where do you suggest I should 
> start, the wiki or the manpage?

Probably expanding man/man7/notmuch-search-terms.7 would be the way to
go.


[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Austin Clements
Quoth Thomas Jost on Jan 17 at 11:50 am:
> There are lots of API changes in gmime 2.6 crypto handling. By adding
> preprocessor directives, it is however possible to add gmime 2.6 compatibility
> while preserving compatibility with gmime 2.4 too.
> 
> This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> 
> This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
> fails (signature verification with signer key unavailable) but this will be 
> hard
> to fix since the new API does not report the reason why a signature 
> verification
> fails (other than the human-readable error message).
> ---
>  mime-node.c  |   56 ++--
>  notmuch-client.h |   28 +++-
>  notmuch-reply.c  |7 
>  notmuch-show.c   |   95 
> ++
>  show-message.c   |4 ++
>  5 files changed, 185 insertions(+), 5 deletions(-)
> 
> diff --git a/mime-node.c b/mime-node.c
> index d26bb44..e575e1c 100644
> --- a/mime-node.c
> +++ b/mime-node.c
> @@ -33,7 +33,11 @@ typedef struct mime_node_context {
>  GMimeMessage *mime_message;
>  
>  /* Context provided by the caller. */
> +#ifdef GMIME_26
> +GMimeCryptoContext *cryptoctx;
> +#else
>  GMimeCipherContext *cryptoctx;
> +#endif
>  notmuch_bool_t decrypt;
>  } mime_node_context_t;
>  
> @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
>  
>  notmuch_status_t
>  mime_node_open (const void *ctx, notmuch_message_t *message,
> - GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
> - mime_node_t **root_out)
> +#ifdef GMIME_26
> + GMimeCryptoContext *cryptoctx,
> +#else
> + GMimeCipherContext *cryptoctx,
> +#endif
> + notmuch_bool_t decrypt, mime_node_t **root_out)
>  {
>  const char *filename = notmuch_message_get_filename (message);
>  mime_node_context_t *mctx;
> @@ -112,12 +120,21 @@ DONE:
>  return status;
>  }
>  
> +#ifdef GMIME_26
> +static int
> +_signature_list_free (GMimeSignatureList **proxy)
> +{
> +g_object_unref (*proxy);
> +return 0;
> +}
> +#else
>  static int
>  _signature_validity_free (GMimeSignatureValidity **proxy)
>  {
>  g_mime_signature_validity_free (*proxy);
>  return 0;
>  }
> +#endif
>  
>  static mime_node_t *
>  _mime_node_create (const mime_node_t *parent, GMimeObject *part)
> @@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, 
> GMimeObject *part)
>   GMimeMultipartEncrypted *encrypteddata =
>   GMIME_MULTIPART_ENCRYPTED (part);
>   node->decrypt_attempted = TRUE;
> +#ifdef GMIME_26
> + GMimeDecryptResult *decrypt_result = NULL;

Reading through the GMime code, it looks like we do have to unref
decrypt_result.  I think this is easy, though.  Right after you call
g_mime_decrypt_result_get_signatures below, do:

  g_object_ref (node->sig_list);
  g_object_unref (decrypt_result);

> + node->decrypted_child = g_mime_multipart_encrypted_decrypt
> + (encrypteddata, node->ctx->cryptoctx, _result, );
> +#else
>   node->decrypted_child = g_mime_multipart_encrypted_decrypt
>   (encrypteddata, node->ctx->cryptoctx, );
> +#endif
>   if (node->decrypted_child) {
> - node->decrypt_success = node->verify_attempted = TRUE;
> + node->decrypt_success = node->verify_attempted =TRUE;

Whitespace.  (There should be no diff on the above line)

> +#ifdef GMIME_26
> + /* This may be NULL if the part is not signed. */
> + node->sig_list = g_mime_decrypt_result_get_signatures 
> (decrypt_result);
> +#else
>   node->sig_validity = 
> g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
> +#endif
>   } else {
>   fprintf (stderr, "Failed to decrypt part: %s\n",
>(err ? err->message : "no error explanation given"));
> @@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, 
> GMimeObject *part)
>"(must be exactly 2)\n",
>node->nchildren);
>   } else {
> +#ifdef GMIME_26
> + GMimeSignatureList *sig_list = g_mime_multipart_signed_verify
> + (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, );
> + node->verify_attempted = TRUE;
> + node->sig_list = sig_list;

Just a nit.  This could be
  node->sig_list = g_mime_multipart_signed_verify ( ... )
To me, the local variable just makes this code more verbose without
adding anything.  Up to you.

> +
> + if (!sig_list)
> + fprintf (stderr, "Failed to verify signed part: %s\n",
> +  (err ? err->message : "no error explanation given"));
> +#else
>   /* For some reason the GMimeSignatureValidity returned
>* here is not a const (inconsistent with 

[PATCH 2/2] emacs: fix typo in notmuch-hello

2012-01-17 Thread Dmitry Kurochkin
---
 emacs/notmuch-hello.el |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index a71f3ce..aed1fb3 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -509,7 +509,7 @@ Complete list of currently available key bindings:
   :action (lambda (widget  ignore)
 (notmuch-hello-search (widget-value widget
;; add an invisible dot to make `widget-end-of-line' ignore
-   ;; trailine spaces in the search widget field
+   ;; trailing spaces in the search widget field
(widget-insert ".")
(put-text-property (1- (point)) (point) 'invisible t)
(widget-insert "\n")
-- 
1.7.8.3



[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box

2012-01-17 Thread Dmitry Kurochkin
This makes `show-trailing-whitespace' happy, i.e. it does not mark the
whole search box line as trailing spaces.

Since the dot is invisible, this change makes no visible difference
for `notmuch-hello'.
---
 emacs/notmuch-hello.el |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 02017ce..a71f3ce 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -508,9 +508,9 @@ Complete list of currently available key bindings:
   (length "Search: ")))
   :action (lambda (widget  ignore)
 (notmuch-hello-search (widget-value widget
-   ;; add an invisible space to make `widget-end-of-line' ignore
+   ;; add an invisible dot to make `widget-end-of-line' ignore
;; trailine spaces in the search widget field
-   (widget-insert " ")
+   (widget-insert ".")
(put-text-property (1- (point)) (point) 'invisible t)
(widget-insert "\n")

-- 
1.7.8.3



[PATCH 2/4] test: Add address cleaning tests.

2012-01-17 Thread Dmitry Kurochkin
On Tue, 17 Jan 2012 12:52:26 +, David Edmondson  wrote:
> Including some more test framework in test-lib.el.
> ---
>  test/address-cleaning.el |   29 +
>  test/address-cleaning.sh |   11 +++
>  test/notmuch-test|1 +
>  test/test-lib.el |   29 +
>  4 files changed, 70 insertions(+), 0 deletions(-)
>  create mode 100644 test/address-cleaning.el
>  create mode 100755 test/address-cleaning.sh
> 

Since test/ directory is used for all kind of tests not just Emacs
UI-specific, so I think address-cleaning.* files should be
emacs-address-cleaning.

Regards,
  Dmitry

> diff --git a/test/address-cleaning.el b/test/address-cleaning.el
> new file mode 100644
> index 000..59e8d92
> --- /dev/null
> +++ b/test/address-cleaning.el
> @@ -0,0 +1,29 @@
> +(defun notmuch-test-address-cleaning-1 ()
> +  (notmuch-test-compare (notmuch-show-clean-address "dme at dme.org")
> + "dme at dme.org"))
> +
> +(defun notmuch-test-address-cleaning-2 ()
> +  (let* ((input '("foo at bar.com"
> +   ""
> +   "Foo Bar "
> +   "foo at bar.com "
> +   "\"Foo Bar\" "))
> +  (expected '("foo at bar.com"
> +  "foo at bar.com"
> +  "Foo Bar "
> +  "foo at bar.com"
> +  "Foo Bar "))
> +  (output (mapcar #'notmuch-show-clean-address input)))
> +(notmuch-test-compare output expected)))
> +
> +(defun notmuch-test-address-cleaning-3 ()
> +  (let* ((input '("?? "
> +   "foo (at home) "
> +   "foo [at home] "
> +   "Foo Bar"))
> +  (expected '("?? "
> +  "foo (at home) "
> +  "foo [at home] "
> +  "Foo Bar"))
> +  (output (mapcar #'notmuch-show-clean-address input)))
> +(notmuch-test-compare output expected)))
> diff --git a/test/address-cleaning.sh b/test/address-cleaning.sh
> new file mode 100755
> index 000..7ec011a
> --- /dev/null
> +++ b/test/address-cleaning.sh
> @@ -0,0 +1,11 @@
> +#!/usr/bin/env bash
> +
> +test_description="emacs address cleaning"
> +. test-lib.sh
> +
> +for i in 1 2 3; do
> +test_emacs_expect_t "notmuch-test-address-clean-$i" \
> +'(load "address-cleaning.el") (notmuch-test-address-cleaning-'$i')'
> +done
> +
> +test_done
> diff --git a/test/notmuch-test b/test/notmuch-test
> index d034f99..7768c32 100755
> --- a/test/notmuch-test
> +++ b/test/notmuch-test
> @@ -53,6 +53,7 @@ TESTS="
>hooks
>argument-parsing
>emacs-test-functions.sh
> +  address-cleaning.sh
>  "
>  TESTS=${NOTMUCH_TESTS:=$TESTS}
>  
> diff --git a/test/test-lib.el b/test/test-lib.el
> index 3b817c3..cf8a46d 100644
> --- a/test/test-lib.el
> +++ b/test/test-lib.el
> @@ -20,6 +20,8 @@
>  ;;
>  ;; Authors: Dmitry Kurochkin 
>  
> +(require 'cl);; This code is generally used uncompiled.
> +
>  ;; `read-file-name' by default uses `completing-read' function to read
>  ;; user input.  It does not respect `standard-input' variable which we
>  ;; use in tests to provide user input.  So replace it with a plain
> @@ -76,3 +78,30 @@ nothing."
>  
>  (add-hook-counter 'notmuch-hello-mode-hook)
>  (add-hook-counter 'notmuch-hello-refresh-hook)
> +
> +;; Functions to help when writing tests:
> +
> +(defun notmuch-test-reporter (output expected)
> +  "Report that the `output' does not match the `expected' result."
> +  (concat "Expect:\t" (prin1-to-string expected) "\n"
> +   "Output:\t" (prin1-to-string output) "\n"))
> +
> +(defun notmuch-test-unsimilar (output expected)
> +  "`output' and `expected' are dissimilar. Show a summary of
> +the differences, ignoring similarities."
> +  (cond ((and (listp output)
> +   (listp expected))
> +  (apply #'concat (loop for o in output
> +for e in expected
> +if (not (equal o e))
> +collect (notmuch-test-reporter o e
> +
> + (t
> +  ;; Catch all case.
> +  (notmuch-test-reporter output expected
> +
> +(defun notmuch-test-compare (output expected)
> +  "Compare `output' with `expected'. Report any discrepencies."
> +  (if (equal output expected)
> +  t
> +(notmuch-test-unsimilar output expected)))
> -- 
> 1.7.7.3
> 
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/4] test: Add `test_emacs_expect_t'.

2012-01-17 Thread Dmitry Kurochkin
On Tue, 17 Jan 2012 12:52:25 +, David Edmondson  wrote:
> Add a new test function to allow simpler testing of emacs
> functionality.
> 
> `test_emacs_expect_t' takes two arguments:
>   - the name of the test,
>   - some lisp to evaluate.
> 
> The test passes if the lisp returns `t', otherwise it fails and the
> output is reported to the tester.

-1

This is not what I suggested.  I do not like the approach when a single
function is used to both declare a subtest and test for result (as
opposed to test_begin_subtest).  The fact that it is possible to write
tests in two different ways makes it hard to maintain and improve the
test framework (one example would be known broken test support).  I
consider the proper way to write tests to be using the
test_begin_subtest function.  Other functions are not currently
deprecated, but I am against adding new code that make the situation
worse.

Also, please consider documenting new functions in README.

Regards,
  Dmitry

> ---
>  test/emacs-test-functions.sh |8 
>  test/notmuch-test|1 +
>  test/test-lib.sh |   24 
>  3 files changed, 33 insertions(+), 0 deletions(-)
>  create mode 100755 test/emacs-test-functions.sh
> 
> diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh
> new file mode 100755
> index 000..969cc78
> --- /dev/null
> +++ b/test/emacs-test-functions.sh
> @@ -0,0 +1,8 @@
> +#!/usr/bin/env bash
> +
> +test_description="emacs test function sanity"
> +. test-lib.sh
> +
> +test_emacs_expect_t "emacs test function sanity" 't'
> +
> +test_done
> diff --git a/test/notmuch-test b/test/notmuch-test
> index 6a99ae3..d034f99 100755
> --- a/test/notmuch-test
> +++ b/test/notmuch-test
> @@ -52,6 +52,7 @@ TESTS="
>python
>hooks
>argument-parsing
> +  emacs-test-functions.sh
>  "
>  TESTS=${NOTMUCH_TESTS:=$TESTS}
>  
> diff --git a/test/test-lib.sh b/test/test-lib.sh
> index 7c9ce24..15da973 100644
> --- a/test/test-lib.sh
> +++ b/test/test-lib.sh
> @@ -503,6 +503,30 @@ test_expect_equal_file ()
>  fi
>  }
>  
> +test_emacs_expect_t () {
> + test "$#" = 2 || error "bug in the test script: not 2 parameters to 
> test_emacs_expect_t"
> + test_reset_state_
> + if ! test_skip "$1"
> + then
> + # We cannot call 'test_emacs' in a subshell, because
> + # the setting of EMACS_SERVER would not persist
> + # throughout a sequence of tests, so we use a
> + # temporary file.
> + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi
> + output="$tmp/test_emacs_output.$$"
> + test_emacs "$2" >"${output}"
> + result=$(cat "${output}")
> + rm -f "${output}"
> +
> + if [ "$result" == t ]
> + then
> + test_ok_ "$1"
> + else
> + test_failure_ "$1" "$(eval printf ${result})"
> + fi
> + fi
> +}
> +
>  NOTMUCH_NEW ()
>  {
>  notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found 
> [0-9]* total file'
> -- 
> 1.7.7.3
> 
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


Notmuch fails to build with gmime 2.6.4

2012-01-17 Thread hollun...@lavabit.com
Hi there. I've seen gmime related discussion but it's hard to follow using
a web interface, so here's my bug report.

Arch Linux x86_64
gmime 2.6.4
notmuch git, last commit: 8ea82928b91e847298e4586f9db9734e727a418a

Build error:

CC -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector
--param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 command-line-arguments.o
CC -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector
--param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 debugger.o
In file included from debugger.c:21:0:
notmuch-client.h:72:5: error: unknown type name ?GMimeSignatureValidity?
notmuch-client.h:86:5: error: unknown type name ?GMimeCipherContext?
notmuch-client.h:297:5: error: unknown type name ?GMimeSignatureValidity?
notmuch-client.h:322:3: error: unknown type name ?GMimeCipherContext?
make: *** [debugger.o] Error 1

Regards,
Philipp




Emacs: Crypto: How to get automatic encryption?

2012-01-17 Thread Antoine Beaupré
On Tue, 17 Jan 2012 09:19:51 +, David Edmondson  wrote:
> On Mon, 16 Jan 2012 23:48:30 -0500, Antoine Beaupr?  anarcat.ath.cx> wrote:
> > Jumping in here, I have modified the previously posted code here to
> > provide me with a more complete solution.
> 
> This looks good. I'll switch over to using it.

Awesome!

> > Code is attached. Obviously, those function names would change if they
> > would be to integrate into notmuch. ;)
> 
> I wondered about pushing to have notmuch do this by default. In general
> I like the idea, but it suffers if a recipient occasionally uses a mail
> client that does not support decryption (phone, PDA, webmail, ...).

Well, it your call: you can disable encryption on the fly by setting the
message to just signing...

I have also found out (to great pains) that it is kind of difficult to
*completely* disable signing or encrypting, as the send-hook will
happily add back the #secure line even if you remove it.

A workaround is to set "mode=none" in the #secure line manually. Maybe
C-c RET C-n could do that instead of just removing the line?

On Tue, 17 Jan 2012 15:39:52 +, David Edmondson  wrote:
> >(if (and force (re-search-forward "<#secure [> >]*>\n" nil t))
> >(replace-match "" nil nil))
> >;; If we can encrypt, do so, else just sign.
> >(if (or force (not (re-search-forward "<#secure [> >]*>\n" nil t)))
> 
> Is this second test for `force' necessary? If `force' is set then you'll
> remove the <#secure..> just above, so it will not be found here.

Yes, it is. If force is true, the search-forward will not be ran at
all. The idea here is that if we do not force (ie. if we're running in
the hook), we do not want to override the existing #secure tags, to
respect the users' choices.

Cheers,

A.

-- 
Antoine Beaupr? +++ R?seau Koumbit Networks +++ +1.514.387.6262 #208



[PATCH v2] emacs: add invisible dot instead of space at the end of notmuch-hello search box

2012-01-17 Thread David Edmondson
+1.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/8d44c5e1/attachment.pgp>


[PATCH 1/1] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Austin Clements
Quoth Mark Walters on Jan 17 at  8:39 pm:
> > > I am happy to make that change. My original patch in the summer was more
> > > like that:
> > > id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com"
> > 
> > Is this the right id?  I couldn't find it in the list archive.
> 
> Sorry I messed up: it should be id:"87mxehqhbl.fsf at r102.config" However
> I have included my current draft along these lines. I think it is
> working but I am not submitting yet: just asking if this is the right
> idea.

In general, yes, I think so.  A few comments on your draft below.

> Best wishes 
> 
> Mark
> 
> From 9e52414b9871369c1cbb5c3e72d833b56bb236d4 Mon Sep 17 00:00:00 2001
> From: Mark Walters 
> Date: Sat, 14 Jan 2012 18:04:22 +
> Subject: [PATCH] Make buttons for attachments allow viewing as well as saving
> 
> Define a keymap for attachment buttons to allow multiple actions.
> Define 3 possible actions:
> save attachment: exactly as currently,
> view attachment: uses mailcap entry,
> view attachment with user chosen program
> 
> Keymap on a button is: s for save, v for view and o for view with
> other program. Default (i.e. enter or mouse button) is save but this
> is configurable in notmuch customize.
> 
> One implementation detail: the view attachment function forces all
> attachments to be "displayed" using mailcap even if emacs could
> display them itself. Thus, for example, text/html appears in a browser
> and text/plain asks whether to save (on a standard debian setup)
> ---
>  emacs/notmuch-show.el |   87 
>  1 files changed, 79 insertions(+), 8 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 03c1f6b..2413caa 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -281,10 +281,21 @@ message at DEPTH in the current thread."
>   (run-hooks 'notmuch-show-markup-headers-hook)
>  
>  (define-button-type 'notmuch-show-part-button-type
> -  'action 'notmuch-show-part-button-action
> +  'action 'notmuch-show-part-button-default
> +  'keymap 'notmuch-show-part-button-map
>'follow-link t
>'face 'message-mml)
>  
> +(defvar notmuch-show-part-button-map
> +  (let ((map (make-sparse-keymap)))
> +   (set-keymap-parent map button-map)
> +   (define-key map "s" 'notmuch-show-part-button-save)
> +   (define-key map "v" 'notmuch-show-part-button-view)
> +   (define-key map "o" 'notmuch-show-part-button-interactively-view)
> +map)
> +  "Submap for button commands")
> +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)

I don't think this fset is necessary.  Actually, I've never seen this
outside of the notmuch code.  It looks like it does appear in code
shipped with Emacs, but only in a handful of places.  All of those
places look like very old code, so maybe this was necessary once upon
a time?

> +
>  (defun notmuch-show-insert-part-header (nth content-type declared-type 
>  name comment)
>(let ((button))
>  (setq button
> @@ -299,7 +310,8 @@ message at DEPTH in the current thread."
>  " ]")
>  :type 'notmuch-show-part-button-type
>  :notmuch-part nth
> -:notmuch-filename name))
> +:notmuch-filename name
> +:notmuch-content-type content-type))
>  (insert "\n")
>  ;; return button
>  button))
> @@ -323,6 +335,28 @@ message at DEPTH in the current thread."
>   ;; ange-ftp, which is reasonable to use here.
>   (mm-write-region (point-min) (point-max) file nil nil nil 
> 'no-conversion t)
>  
> +(defun notmuch-show-view-part (message-id nth content-type)
> +  (let ((process-crypto notmuch-show-process-crypto))
> +(with-temp-buffer
> +  (setq notmuch-show-process-crypto process-crypto)
> +  ;; Always acquires the part via `notmuch part', even if it is
> +  ;; available in the JSON output.
> +  (insert (notmuch-show-get-bodypart-internal message-id nth))
> +  ;; set mm-inlined-types to nil to force an external viewer
> +  (let ((handle (mm-make-handle (current-buffer) (list content-type)))
> + (mm-inlined-types nil))
> + (mm-display-part handle t)
> +
> +(defun notmuch-show-interactively-view-part (message-id nth content-type)
> +  (let ((process-crypto notmuch-show-process-crypto))
> +(with-temp-buffer
> +  (setq notmuch-show-process-crypto process-crypto)
> +  ;; Always acquires the part via `notmuch part', even if it is
> +  ;; available in the JSON output.
> +  (insert (notmuch-show-get-bodypart-internal message-id nth))
> +  (let ((handle (mm-make-handle (current-buffer) (list content-type
> + (mm-interactively-view-part handle)
> +

Yeah.  Though you're right that the duplication is a little annoying.
With the snippet I sent earlier, these could change to, e.g.,

(defun notmuch-show-interactively-view-part (message-id nth content-type)
  (notmuch-with-part-temp-buffer
   

[PATCH v2 5/5] emacs: Use message-citation-line-format in reply

2012-01-17 Thread Adam Wolfe Gordon
Instead of using a static citation line for the first line of the
reply message, use the customizable one defined by message-mode.
This makes it easy for users to customize the reply style, and
retains consistency for users with existing message-mode
customizations.

The test has been updated to reflect how the message will be
formatted with the default value of message-citation-line-format.

---
 emacs/notmuch-mua.el |   19 ---
 test/emacs   |2 +-
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 64e160a..b58f919 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -135,9 +135,22 @@ list."
  (forward-line -1)
(goto-char (point-max)))

-  (insert (format "On %s, %s wrote:\n"
- (cdr (assq 'date original-headers))
- (cdr (assq 'from original-headers
+  (let* ((quoth message-citation-line-format)
+(case-fold-search nil)
+(full-from (cdr (assq 'from original-headers)))
+(from-addr (car (mail-header-parse-address full-from)))
+(from-name (cdr (mail-header-parse-address full-from)))
+(first-name (car (split-string from-name)))
+(last-name (append (cdr (split-string from-name
+(time (date-to-time (cdr (assq 'date original-headers)
+
+   (setq quoth (replace-regexp-in-string "%f" full-from quoth t t))
+   (setq quoth (replace-regexp-in-string "%n" from-addr quoth t t))
+   (setq quoth (replace-regexp-in-string "%N" from-name quoth t t))
+   (setq quoth (replace-regexp-in-string "%F" first-name quoth t t))
+   (setq quoth (replace-regexp-in-string "%L" last-name quoth t t))
+   (setq quoth (format-time-string quoth time))
+   (insert quoth))

   (if plain-parts
  (mapc (lambda (part) (notmuch-mua-insert-part-quoted part)) 
plain-parts)
diff --git a/test/emacs b/test/emacs
index ac47b16..3f59b23 100755
--- a/test/emacs
+++ b/test/emacs
@@ -268,7 +268,7 @@ Subject: Re: Testing message sent via SMTP
 In-Reply-To: 
 Fcc: $(pwd)/mail/sent
 --text follows this line--
-On 01 Jan 2000 12:00:00 -, Notmuch Test Suite  wrote:
+On Sat, Jan 01 2000, Notmuch Test Suite wrote:
 > This is a test that messages are sent via SMTP
 EOF
 test_expect_equal_file OUTPUT EXPECTED
-- 
1.7.5.4



[PATCH v2 4/5] emacs: Use the new JSON reply format.

2012-01-17 Thread Adam Wolfe Gordon
Using the new JSON reply format allows emacs to quote HTML
parts nicely by using mm-display-part to turn them into displayable
text, then quoting them. This is very useful for users who
regularly receive HTML-only email.

The behavior for messages that contain plain text parts should be
unchanged.
---

Here is an updated patch that addresses David's concerns. A separate
patch implementing use of the message-citation-line-format variable
will follow.

 emacs/notmuch-lib.el |8 
 emacs/notmuch-mua.el |   97 +
 2 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 0f856bf..2681634 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -127,6 +127,14 @@ the user hasn't set this variable with the old or new 
value."
   (list 'when (< emacs-major-version 23)
form))

+(defun notmuch-parts-filter-by-type (parts type)
+  "Return a list of message parts with the given type"
+  (let (result)
+(dolist (part (append parts nil) result)
+  (if (string= (cdr (assq 'content-type part)) type)
+ (setq result (append result (list (cdr (assq 'content part)))
+result))
+
 ;; Compatibility functions for versions of emacs before emacs 23.
 ;;
 ;; Both functions here were copied from emacs 23 with the following copyright:
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index d8ab822..64e160a 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -19,6 +19,7 @@
 ;;
 ;; Authors: David Edmondson 

+(require 'json)
 (require 'message)

 (require 'notmuch-lib)
@@ -71,49 +72,81 @@ list."
(push header message-hidden-headers)))
notmuch-mua-hidden-headers))

+(defun notmuch-mua-insert-part-quoted (part)
+  (let ((start (point))
+   limit)
+(insert part)
+(setq limit (point))
+(goto-char start)
+(while (re-search-forward "\\(^\\)[^$]" limit 0)
+  (replace-match "> " nil nil nil 1)
+  ;; We have added two characters to the quotable region
+  (setq limit (+ limit 2)))
+(set-buffer-modified-p nil)))
+
+(defun notmuch-mua-parse-html-part (part)
+  (with-temp-buffer
+(insert part)
+(let ((handle (mm-make-handle (current-buffer) (list "text/html")))
+ (end-of-orig (point-max)))
+  (mm-display-part handle)
+  (delete-region (point-min) end-of-orig)
+  (fill-region (point-min) (point-max))
+  (buffer-substring (point-min) (point-max)
+
 (defun notmuch-mua-reply (query-string  sender reply-all)
-  (let (headers
-   body
-   (args '("reply")))
+  (let ((args '("reply" "--format=json"))
+   reply
+   body)
 (if notmuch-show-process-crypto
(setq args (append args '("--decrypt"
 (if reply-all
(setq args (append args '("--reply-to=all")))
   (setq args (append args '("--reply-to=sender"
 (setq args (append args (list query-string)))
-;; This make assumptions about the output of `notmuch reply', but
-;; really only that the headers come first followed by a blank
-;; line and then the body.
+;; Get the reply object as JSON, and parse it into an elisp object.
 (with-temp-buffer
   (apply 'call-process (append (list notmuch-command nil (list t t) nil) 
args))
   (goto-char (point-min))
-  (if (re-search-forward "^$" nil t)
- (save-excursion
-   (save-restriction
- (narrow-to-region (point-min) (point))
- (goto-char (point-min))
- (setq headers (mail-header-extract)
-  (forward-line 1)
-  (setq body (buffer-substring (point) (point-max
-;; If sender is non-nil, set the From: header to its value.
-(when sender
-  (mail-header-set 'from sender headers))
-(let
-   ;; Overlay the composition window on that being used to read
-   ;; the original message.
-   ((same-window-regexps '("\\*mail .*")))
-  (notmuch-mua-mail (mail-header 'to headers)
-   (mail-header 'subject headers)
-   (message-headers-to-generate headers t '(to subject
-;; insert the message body - but put it in front of the signature
-;; if one is present
-(goto-char (point-max))
-(if (re-search-backward message-signature-separator nil t)
+  (setq reply (aref (json-read) 0)))
+
+;; Start with the prelude, based on the headers of the original message.
+(let* ((original (cdr (assq 'original reply)))
+  (headers (cdr (assq 'headers (assq 'reply reply
+  (original-headers (cdr (assq 'headers original)))
+  (body-parts (cdr (assq 'body original)))
+  (plain-parts (notmuch-parts-filter-by-type body-parts "text/plain"))
+  (html-parts (notmuch-parts-filter-by-type body-parts "text/html")))
+
+  ;; If sender is non-nil, set the From: header to its value.
+  (when sender
+   (mail-header-set 'from sender headers))
+  (let
+ 

[PATCH 1/1] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Aaron Ecay
On Tue, 17 Jan 2012 15:26:03 -0500, Austin Clements  wrote:
> Quoth Mark Walters on Jan 17 at  9:06 am:
> > 
> > > > I wonder if the "problem" comes from me doing things in a non-lispy
> > > > fashion (I am completely new to lisp). Thus
> > > > notmuch-show-part-button-default-action is a variable that gets passed
> > > > around rather than a function.
> > > 
> > > Sorry, I should have looked at the bigger context in this patch.  I
> > > think Jameson was implying that notmuch-show-part-button-default
> > > should change to
> > > 
> > > (defun notmuch-show-part-button-default ( button)
> > >   (interactive)
> > >   (funcall notmuch-show-part-button-default-action button))
> > > 
> > > I would go one step further and say that each action should probably
> > > be a separate function.  That is, break notmuch-show-part-action into
> > > separate functions and simply invoke the appropriate function, rather
> > > than performing a fixed data dispatch.  This would be more flexible
> > > and Lispy.  It may be that your approach works out better, but I'd at
> > > least give this a shot.
> > 
> > I am happy to make that change. My original patch in the summer was more
> > like that:
> > id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com"
> 
> Is this the right id?  I couldn't find it in the list archive.
> 
> > Is that more what you had in mind? (Only in broad terms: Obviously I
> > would need to add in the customization and default function etc). I
> > decided that I didn't like the code duplication (but I am completely new
> > to lisp) which is why I changed it for this submission.
> 
> Yes, I wondered about this, too.  It seems like at worst the
> notmuch-show-process-crypto stuff would be duplicated.  This might be
> little enough that it's not worth worrying about, or it might be worth
> introducing something like
> 
> (defun notmuch-with-temp-part-buffer (message-id nth action)
>   (let ((process-crypto notmuch-show-process-crypto))
> (with-temp-buffer
>   (setq notmuch-show-process-crypto process-crypto)
>   ;; Always acquires the part via `notmuch part', even if it is
>   ;; available in the JSON output.
>   (insert (notmuch-show-get-bodypart-internal message-id nth))
>   (funcall action
> 
> You could also do this as a macro, but that definitely seems like
> overkill.

It seems to me that a macro is in fact the best solution.  If you do it
with a function, you need two defuns per action: one to do the actual
work:
(defun notmuch-show-part-button-whatever-worker ()
  ;; do stuff...
)
and one that says:
(defun notmuch-show-part-button-whatever ()
  (notmuch-with-temp-part-buffer
   id part-number #'notmuch-show-part-button-whatever-worker))

It would be the latter function that the key would be bound to.  If a
macro is used, the split between the worker and glue fns can be
abandoned, and only one function is needed:
(defun notmuch-show-part-button-whatever ()
  (notmuch-with-temp-part-buffer
  ;; do stuff...
  ))

A further advantage is if interactive arguments (e.g. C-u prefix) are
needed for the function, there is no need to thread them through as
arguments of notmuch-with-temp-part-buffer.

-- 
Aaron Ecay


Emacs: Crypto: How to get automatic encryption?

2012-01-17 Thread David Edmondson
>(if (and force (re-search-forward "<#secure [> >]*>\n" nil t))
>  (replace-match "" nil nil))
>;; If we can encrypt, do so, else just sign.
>(if (or force (not (re-search-forward "<#secure [> >]*>\n" nil t)))

Is this second test for `force' necessary? If `force' is set then you'll
remove the <#secure..> just above, so it will not be found here.

>  (if (anarcat/message-guess-encryption)
>  (insert "<#secure method=pgpmime mode=signencrypt>\n")
>(insert "<#secure method=pgpmime mode=sign>\n"))
>)
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/90e8e822/attachment.pgp>


[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Austin Clements
Quoth Thomas Jost on Jan 17 at 11:48 am:
> On Mon, 16 Jan 2012 22:47:14 -0500, Austin Clements  
> wrote:
> > Quoth Thomas Jost on Jan 17 at 12:56 am:
> > > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> > > 
> > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, 
> > > the
> > > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto 
> > > test
> > > fails (signature verification with signer key unavailable) but this will 
> > > be hard
> > > to fix since the new API does not report the reason why a signature 
> > > verification
> > > fails (other than the human-readable error message).
> > 
> > What is the result of this failing test?
> 
> The test looks like that:
> 
> FAIL   signature verification with signer key unavailable
>--- crypto.4.expected   2012-01-16 23:05:06.765651183 +
>+++ crypto.4.output 2012-01-16 23:05:06.765651183 +
>@@ -12,9 +12,7 @@
>  "Bcc": "",
>  "Date": "01 Jan 2000 12:00:00 -"},
>  "body": [{"id": 1,
>- "sigstatus": [{"status": "error",
>- "keyid": "6D92612D94E46381",
>- "errors": 2}],
>+ "sigstatus": [],
>  "content-type": "multipart/signed",
>  "content": [{"id": 2,
>  "content-type": "text/plain",
>Failed to verify signed part: gpg: keyblock resource 
> `/home/schnouki/dev/notmuch/test/tmp.crypto/gnupg/pubring.gpg': file open 
> error
>gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux)
>gpg: Signature made Mon Jan 16 23:05:06 2012 UTC using RSA key ID 
> 94E46381
>gpg: Can't check signature: public key not found
> 
> So basically if a signer public key is missing, we can't get the status
> signature: empty "sigstatus" field in the JSON output, "Unknown
> signature status" in Emacs.
> 
> IMHO this is a bug in gmime 2.6, and I think I know what causes it. I'll
> file a bug in gmime and hopefully they'll find a cleaner way to fix it
> than the one I came up with :)

Oh, okay.  That does seem like a bug in GMime.  Do you think it would
be possible to mark this test as "broken" if notmuch is using GMime
2.6?  Off the top of my head, I can't think of an easy way to plumb
that information through to the test suite.  I don't think we should
push any patches that knowingly break a test, even if it's in just one
configuration.

> > 
> > > ---
> > >  mime-node.c  |   50 ++-
> > >  notmuch-client.h |   27 ++-
> > >  notmuch-reply.c  |7 
> > >  notmuch-show.c   |   97 
> > > ++
> > >  show-message.c   |4 ++
> > >  5 files changed, 181 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/mime-node.c b/mime-node.c
> > > index d26bb44..ae2473d 100644
> > > --- a/mime-node.c
> > > +++ b/mime-node.c
> > > @@ -33,7 +33,11 @@ typedef struct mime_node_context {
> > >  GMimeMessage *mime_message;
> > >  
> > >  /* Context provided by the caller. */
> > > +#ifdef GMIME_26
> > > +GMimeCryptoContext *cryptoctx;
> > > +#else
> > >  GMimeCipherContext *cryptoctx;
> > > +#endif
> > >  notmuch_bool_t decrypt;
> > >  } mime_node_context_t;
> > >  
> > > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)
> > >  
> > >  notmuch_status_t
> > >  mime_node_open (const void *ctx, notmuch_message_t *message,
> > > - GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
> > > - mime_node_t **root_out)
> > > +#ifdef GMIME_26
> > > + GMimeCryptoContext *cryptoctx,
> > > +#else
> > > + GMimeCipherContext *cryptoctx,
> > > +#endif
> > > + notmuch_bool_t decrypt, mime_node_t **root_out)
> > >  {
> > >  const char *filename = notmuch_message_get_filename (message);
> > >  mime_node_context_t *mctx;
> > > @@ -112,12 +120,21 @@ DONE:
> > >  return status;
> > >  }
> > >  
> > > +#ifdef GMIME_26
> > > +static int
> > > +_signature_list_free (GMimeSignatureList **proxy)
> > > +{
> > > +g_object_unref (*proxy);
> > > +return 0;
> > > +}
> > > +#else
> > >  static int
> > >  _signature_validity_free (GMimeSignatureValidity **proxy)
> > >  {
> > >  g_mime_signature_validity_free (*proxy);
> > >  return 0;
> > >  }
> > > +#endif
> > >  
> > >  static mime_node_t *
> > >  _mime_node_create (const mime_node_t *parent, GMimeObject *part)
> > > @@ -165,11 +182,23 @@ _mime_node_create (const mime_node_t *parent, 
> > > GMimeObject *part)
> > >   GMimeMultipartEncrypted *encrypteddata =
> > >   GMIME_MULTIPART_ENCRYPTED (part);
> > >   node->decrypt_attempted = TRUE;
> > > +#ifdef GMIME_26
> > > + GMimeDecryptResult *decrypt_result = g_mime_decrypt_result_new ();
> > 
> > I think g_mime_multipart_encrypted_decrypt allocates the
> > GMimeDecryptResult for you, so this will just leak memory.
> 
> You're right, fixed. Will it 

[PATCH v2 3/3] search: Support automatic tag exclusions

2012-01-17 Thread Austin Clements
Quoth David Edmondson on Jan 17 at  9:08 am:
> On Mon, 16 Jan 2012 15:16:24 -0700, Jeremy Nickurak  
> wrote:
> > On Mon, Jan 16, 2012 at 12:28, Austin Clements  wrote:
> > >> Having "deleted" and "spam" as default settings in the configuration
> > >> file might be more reasonable.
> > 
> > If I read correctly:
> > 
> > 1) If no exclude options are in the config file, none should be used.
> 
> Yes.
> 
> > 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config
> 
> I might argue between 'should' and 'could', but the sense is correct.

Oh, I think I see.  I don't know if I can do precisely that, since the
config code doesn't know if it's being called from setup, but is
something like this essentially what you're suggesting?

if (notmuch_config_get_auto_exclude_tags (config, ) == NULL) {
if (is_new) {
const char *tags[] = { "deleted", "spam" };
notmuch_config_set_auto_exclude_tags (config, tags, 2);
} else {
notmuch_config_set_auto_exclude_tags (config, NULL, 0);
}
}

(where is_new is TRUE if this is a brand-new config file)


[PATCH] emacs: have notmuch-search-archive-thread use -next-thread function

2012-01-17 Thread Aaron Ecay
+1

-- 
Aaron Ecay


[PATCH 3/6] emacs: add message archiving functions

2012-01-17 Thread Aaron Ecay
On Tue, 17 Jan 2012 10:05:28 -0800, Jameson Graef Rollins  wrote:
> This adds two new message archiving functions that parallel the thread
> archiving functions: notmuch-show-archive-message{,-then-next}.  The
> former also takes a prefix argument to unarchive the message (ie. put
> back in inbox).
> ---
>  emacs/notmuch-show.el |   17 +
>  1 files changed, 17 insertions(+), 0 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index ee9ef62..207949c 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -1485,6 +1485,23 @@ buffer."
>(notmuch-show-archive-thread)
>(notmuch-show-next-thread))
>  
> +(defun notmuch-show-archive-message ( unarchive)
> +  "Archive the current message.
> +
> +If a prefix argument is given, the message will be
> +\"unarchived\" (ie. the \"inbox\" tag will be added instead of
> +removed)."
> +  (interactive)

If this function uses the prefix arg, its interactive call should be
?(interactive "P")?.  This applies equally to the -thread variant in
patch 2/6, but I made the comment here because that diff doesn?t show
the function contiguously.

-- 
Aaron Ecay


[PATCH 1/6] emacs: break up notmuch-show-archive-thread-internal into two generally useful functions

2012-01-17 Thread Aaron Ecay
On Tue, 17 Jan 2012 10:05:26 -0800, Jameson Graef Rollins  wrote:
> Brake up notmuch-show-archive-thread-internal into two new functions:
> 
> notmuch-show-tag-thread-internal: applies a tag to all messages in
> thread.  If option remove flag is t, tags will be removed instead of
> added.
> 
> notmuch-show-next-thread: moves to the next thread in the search
> result.  If given a prefix, will show the next result, otherwise will
> just move to it in the search view.
> 
> Two new interactive functions, notmuch-show-{add,remove}-tag-thread,
> are also added.  Together, these provide a better suit of thread
> tagging and navigation tools.
> 
> The higher level thread archiving functions are modified to use these
> new functions.
> ---
>  emacs/notmuch-show.el |   33 ++---
>  1 files changed, 26 insertions(+), 7 deletions(-)
> 
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 03c1f6b..3625afd 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -1421,12 +1421,29 @@ argument, hide all of the messages."
>(interactive)
>(backward-button 1))
>  
> -(defun notmuch-show-archive-thread-internal (show-next)
> -  ;; Remove the tag from the current set of messages.
> +(defun notmuch-show-tag-thread-internal (tag  remove)
> +  ;; Add tag to the current set of messages.  If the remove switch is
> +  ;; given, tags will be removed instead of added.

This should be a docstring instead of a comment.  (This applies equally
to the old version)

-- 
Aaron Ecay


[PATCH 2/3] test: Add `test_emacs_expect_t'.

2012-01-17 Thread David Edmondson
On Tue, 17 Jan 2012 18:49:36 +0400, Dmitry Kurochkin  wrote:
> > +   # We cannot call 'test_emacs' in a subshell, because
> > +   # the setting of EMACS_SERVER would not persist
> > +   # throughout a sequence of tests, so we use a
> > +   # temporary file.
> > +   tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi
> > +   output="$tmp/test_emacs_output.$$"
> > +   test_emacs "$1" > "${output}"
> > +   result=$(cat "${output}")
> > +   rm -f "${output}"
> 
> I wonder if there is any bash trick which can help here?

I'm not aware of one, but I'm not a bash expert.

> Another option is to start emacs server before using test_emacs in
> subshell.  See emacs-subject-to-filename for an example.  I think this
> is a better option than using a temporary file.

I think that's a very poor option. Forcing knowledge the breakage into
all of the users may make applying any future fix more difficult.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/3df8fb09/attachment.pgp>


show-mode message/thread archiving improvements

2012-01-17 Thread Aaron Ecay
+1 on this series from me.  (Minor comments on a couple of the patches
to follow.)

-- 
Aaron Ecay


[PATCH] fix .gitignore for gzipped man pages

2012-01-17 Thread David Bremner
On Tue, 17 Jan 2012 20:16:03 +0200, Jani Nikula  wrote:
> ---
>  .gitignore |1 -
>  man/.gitignore |2 ++

pushed,

d


[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Tomi Ollila
On Tue, 17 Jan 2012 11:50:53 +0100, Thomas Jost  
wrote:
> There are lots of API changes in gmime 2.6 crypto handling. By adding
> preprocessor directives, it is however possible to add gmime 2.6 compatibility
> while preserving compatibility with gmime 2.4 too.
> 
> This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> 
> This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
> fails (signature verification with signer key unavailable) but this will be 
> hard
> to fix since the new API does not report the reason why a signature 
> verification
> fails (other than the human-readable error message).
> ---

LGTM. Some whitespace things but most of those were there already;
I'd have one uncrustify round to be applied to the source and after
that be more strict about those...

actually gmime 2.4 has GMIME_CHECK_VERSION defined as
g_mime_check_version (major, minor, micro) so the comment about it
is not entirely accurate (it is unusable in our context, though)


Tomi


Partial words on notmuch search?

2012-01-17 Thread Austin Clements
Quoth Jani Nikula on Jan 17 at  7:43 pm:
> On Mon, 16 Jan 2012 21:34:31 -0500, Austin Clements  
> wrote:
> > Quoth Andrei Popescu on Jan 16 at 10:21 pm:
> > > This is also interesting:
> > > $ notmuch count 'debian'
> > > 65888
> > > $ notmuch count 'dEbian'
> > > 65888
> > > $ notmuch count 'Debian'
> > > 65887
> > 
> > The first two will match stemmed versions of "debian" such as
> > "debian's" and "debianed".  However, starting a term with a capital
> > letter suppresses stemming (because it suggests that it's a name,
> > which you wouldn't want to modify), so your last query matches only
> > the term "debian".  This is probably documented somewhere, though I
> > don't know where.
> 
> Interesting. Is this done when adding the terms to the database, or when
> searching? I presume the latter. How much control does notmuch have over
> this?

This is getting a bit out of my depth, but I believe indexing is done
with both stemmed and unstemmed versions of all terms (if stemming is
enabled) so that search can use either.

For indexing, Notmuch can set the stemmer (or no stemmer).  Xapian
provides stemmers for a variety of languages:
  
http://xapian.org/docs/apidoc/html/classXapian_1_1Stem.html#6c46cedf2047b159a7e4c9d4468242b1

For query parsing, Notmuch can set both the stemmer and a "stemming
strategy" that controls when it stems or doesn't stem terms:
  
http://xapian.org/docs/apidoc/html/classXapian_1_1QueryParser.html#c7dc3b55b6083bd3ff98fc8b2726c8fd


[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.

2012-01-17 Thread David Edmondson
(And for the list...)

On Tue, 17 Jan 2012 18:20:04 +0400, Dmitry Kurochkin  wrote:
> Can you please elaborate why this is needed?

This code:

# wait until the emacs server is up
until test_emacs '()' 2>/dev/null; do
sleep 1
done

outputs 'nil', so the first caller to test_emacs has 'nil\n' prepended
to their expected output.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/af9c04db/attachment.pgp>


[PATCH 2/3] test: Add `test_emacs_expect_t'.

2012-01-17 Thread David Edmondson
On Tue, 17 Jan 2012 18:26:41 +0400, Dmitry Kurochkin  wrote:
> Sorry, I still do not understand why we can not implement
> test_emacs_expect_t() like:
> 
>   result=${test_emacs $@}
>   test_expect_equal $result t
> 
> Can you please explain?

In the failure case test_expect_equal does:

  test_failure_ "$test_subtest_name" "$(diff -u $testname.expected 
$testname.output)"

that diff output is not useful here, because the test harness doesn't
have any expected output other than `t' with which to diff the actual
output.

The emacs-address-cleaning test shows how we will provide expected
vs. actual output directly from within emacs, making it easier for the
developer to figure out what went wrong.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/9aca0d02/attachment.pgp>


[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box

2012-01-17 Thread David Edmondson
On Tue, 17 Jan 2012 18:13:26 +0400, Dmitry Kurochkin  wrote:
> On Tue, 17 Jan 2012 14:08:58 +, David Edmondson  wrote:
> > On Tue, 17 Jan 2012 17:24:45 +0400, Dmitry Kurochkin  > gmail.com> wrote:
> > > This makes `show-trailing-whitespace' happy, i.e. it does not mark the
> > > whole search box line as trailing spaces.
> > 
> > Why should `whitespace-mode' be active in `notmuch-hello' buffers?
> 
> I do not say that it should be active in notmuch-hello.
> 
> For me `show-trailing-whitespace' is activated everywhere with some
> exceptions.  Notmuch-hello is one of these exceptions.  This change make
> it one step closer to removing the exception.

Okay. Please add a comment to explain why it is a . rather than a space,
then +1.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/140e24aa/attachment.pgp>


[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
On Tue, 17 Jan 2012 14:48:34 +0200, Tomi Ollila  wrote:
> On Tue, 17 Jan 2012 11:50:53 +0100, Thomas Jost  
> wrote:
> > There are lots of API changes in gmime 2.6 crypto handling. By adding
> > preprocessor directives, it is however possible to add gmime 2.6 
> > compatibility
> > while preserving compatibility with gmime 2.4 too.
> > 
> > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> > 
> > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
> > fails (signature verification with signer key unavailable) but this will be 
> > hard
> > to fix since the new API does not report the reason why a signature 
> > verification
> > fails (other than the human-readable error message).
> > ---
> 
> LGTM. Some whitespace things but most of those were there already;
> I'd have one uncrustify round to be applied to the source and after
> that be more strict about those...

Thanks! I'll fix the whitespace issues in these patches when the source
in Git is uncrustified then.

> actually gmime 2.4 has GMIME_CHECK_VERSION defined as
> g_mime_check_version (major, minor, micro) so the comment about it
> is not entirely accurate (it is unusable in our context, though)

Oops, yes. What I really meant is that GMIME_MAJOR_VERSION is not
available as a preprocessor constant in 2.4, and GMIME_CHECK_VERSION is
unusable in our context since it just calls a runtime function.

By the way, how do you guys feel about setting GMIME_26 in
notmuch-client.h? Is that good enough, or should it be done in configure
so that gcc is called with "-DGMIME_26"?

I filed a bug about gmime 2.6 incorrect handling of signatures with
missing public keys: https://bugzilla.gnome.org/show_bug.cgi?id=668085.
A patch is attached there, feel free to test and comment.

(Arch Linux users: I made a little PKGBUILD that includes this patch if
you want to build your own gmime 2.6.4:
http://fichiers.schnouki.net/tmp/gmime-2.6.4-1.src.tar.gz)

Best regards,

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/e5f7d377/attachment-0001.pgp>


[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box

2012-01-17 Thread David Edmondson
On Tue, 17 Jan 2012 17:24:45 +0400, Dmitry Kurochkin  wrote:
> This makes `show-trailing-whitespace' happy, i.e. it does not mark the
> whole search box line as trailing spaces.

Why should `whitespace-mode' be active in `notmuch-hello' buffers?
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/039d0462/attachment.pgp>


[PATCH 3/3] test: Add address cleaning tests.

2012-01-17 Thread David Edmondson
Including some more test framework in test-lib.el.
---

notmuch-test-address-cleaning-3 currently fails, in order that you can
see the output format in that case.

 test/emacs-address-cleaning.el |   29 +
 test/emacs-address-cleaning.sh |   12 
 test/notmuch-test  |1 +
 test/test-lib.el   |   29 +
 4 files changed, 71 insertions(+), 0 deletions(-)
 create mode 100644 test/emacs-address-cleaning.el
 create mode 100755 test/emacs-address-cleaning.sh

diff --git a/test/emacs-address-cleaning.el b/test/emacs-address-cleaning.el
new file mode 100644
index 000..59e8d92
--- /dev/null
+++ b/test/emacs-address-cleaning.el
@@ -0,0 +1,29 @@
+(defun notmuch-test-address-cleaning-1 ()
+  (notmuch-test-compare (notmuch-show-clean-address "dme at dme.org")
+   "dme at dme.org"))
+
+(defun notmuch-test-address-cleaning-2 ()
+  (let* ((input '("foo at bar.com"
+ ""
+ "Foo Bar "
+ "foo at bar.com "
+ "\"Foo Bar\" "))
+(expected '("foo at bar.com"
+"foo at bar.com"
+"Foo Bar "
+"foo at bar.com"
+"Foo Bar "))
+(output (mapcar #'notmuch-show-clean-address input)))
+(notmuch-test-compare output expected)))
+
+(defun notmuch-test-address-cleaning-3 ()
+  (let* ((input '("?? "
+ "foo (at home) "
+ "foo [at home] "
+ "Foo Bar"))
+(expected '("?? "
+"foo (at home) "
+"foo [at home] "
+"Foo Bar"))
+(output (mapcar #'notmuch-show-clean-address input)))
+(notmuch-test-compare output expected)))
diff --git a/test/emacs-address-cleaning.sh b/test/emacs-address-cleaning.sh
new file mode 100755
index 000..1a6eff5
--- /dev/null
+++ b/test/emacs-address-cleaning.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+test_description="emacs address cleaning"
+. test-lib.sh
+
+for i in 1 2 3; do
+test_begin_subtest "notmuch-test-address-clean-$i"
+test_emacs_expect_t \
+   '(load "emacs-address-cleaning.el") 
(notmuch-test-address-cleaning-'$i')'
+done
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index d034f99..3f1740c 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -53,6 +53,7 @@ TESTS="
   hooks
   argument-parsing
   emacs-test-functions.sh
+  emacs-address-cleaning.sh
 "
 TESTS=${NOTMUCH_TESTS:=$TESTS}

diff --git a/test/test-lib.el b/test/test-lib.el
index 3b817c3..cf8a46d 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -20,6 +20,8 @@
 ;;
 ;; Authors: Dmitry Kurochkin 

+(require 'cl)  ;; This code is generally used uncompiled.
+
 ;; `read-file-name' by default uses `completing-read' function to read
 ;; user input.  It does not respect `standard-input' variable which we
 ;; use in tests to provide user input.  So replace it with a plain
@@ -76,3 +78,30 @@ nothing."

 (add-hook-counter 'notmuch-hello-mode-hook)
 (add-hook-counter 'notmuch-hello-refresh-hook)
+
+;; Functions to help when writing tests:
+
+(defun notmuch-test-reporter (output expected)
+  "Report that the `output' does not match the `expected' result."
+  (concat "Expect:\t" (prin1-to-string expected) "\n"
+ "Output:\t" (prin1-to-string output) "\n"))
+
+(defun notmuch-test-unsimilar (output expected)
+  "`output' and `expected' are dissimilar. Show a summary of
+the differences, ignoring similarities."
+  (cond ((and (listp output)
+ (listp expected))
+(apply #'concat (loop for o in output
+  for e in expected
+  if (not (equal o e))
+  collect (notmuch-test-reporter o e
+
+   (t
+;; Catch all case.
+(notmuch-test-reporter output expected
+
+(defun notmuch-test-compare (output expected)
+  "Compare `output' with `expected'. Report any discrepencies."
+  (if (equal output expected)
+  t
+(notmuch-test-unsimilar output expected)))
-- 
1.7.7.3



[PATCH 2/3] test: Add `test_emacs_expect_t'.

2012-01-17 Thread David Edmondson
Add a new test function to allow simpler testing of emacs
functionality.

`test_emacs_expect_t' takes one argument - a list expression to
evaluate. The test passes if the expression returns `t', otherwise it
fails and the output is reported to the tester.
---

Re-worked as Dmitry suggested.

 test/README  |8 
 test/emacs-test-functions.sh |9 +
 test/notmuch-test|1 +
 test/test-lib.sh |   33 +
 4 files changed, 51 insertions(+), 0 deletions(-)
 create mode 100755 test/emacs-test-functions.sh

diff --git a/test/README b/test/README
index bde6db0..9dbe2ee 100644
--- a/test/README
+++ b/test/README
@@ -189,6 +189,14 @@ library for your script to use.
tests that may run in the same Emacs instance.  Use `let' instead
so the scope of the changed variables is limited to a single test.

+ test_emacs_expect_t 
+
+  This function executes the provided emacs lisp script within
+  emacs in a manner similar to 'test_emacs'. The expressions should
+  return the value `t' to indicate that the test has passed. If the
+  test does not return `t' then it is considered failed and all data
+  returned by the test is reported to the tester.
+
  test_done

Your test script must have test_done at the end.  Its purpose
diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh
new file mode 100755
index 000..0e1f9fc
--- /dev/null
+++ b/test/emacs-test-functions.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+test_description="emacs test function sanity"
+. test-lib.sh
+
+test_begin_subtest "emacs test function sanity"
+test_emacs_expect_t 't'
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index 6a99ae3..d034f99 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -52,6 +52,7 @@ TESTS="
   python
   hooks
   argument-parsing
+  emacs-test-functions.sh
 "
 TESTS=${NOTMUCH_TESTS:=$TESTS}

diff --git a/test/test-lib.sh b/test/test-lib.sh
index 7c9ce24..4b05760 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -503,6 +503,39 @@ test_expect_equal_file ()
 fi
 }

+test_emacs_expect_t () {
+   test "$#" = 1 || error "bug in the test script: not 1 parameter to 
test_emacs_expect_t"
+
+   # Run the test.
+   if ! test_skip "$test_subtest_name"
+   then
+   # We cannot call 'test_emacs' in a subshell, because
+   # the setting of EMACS_SERVER would not persist
+   # throughout a sequence of tests, so we use a
+   # temporary file.
+   tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi
+   output="$tmp/test_emacs_output.$$"
+   test_emacs "$1" > "${output}"
+   result=$(cat "${output}")
+   rm -f "${output}"
+   fi
+
+   # Restore state after the test.
+   exec 1>&6 2>&7  # Restore stdout and stderr
+   inside_subtest=
+
+   # Report success/failure.
+   if ! test_skip "$test_subtest_name"
+   then
+   if [ "$result" == t ]
+   then
+   test_ok_ "$test_subtest_name"
+   else
+   test_failure_ "$test_subtest_name" "$(eval printf 
${result})"
+   fi
+   fi
+}
+
 NOTMUCH_NEW ()
 {
 notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* 
total file'
-- 
1.7.7.3



[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.

2012-01-17 Thread David Edmondson
---
 test/test-lib.sh |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/test/test-lib.sh b/test/test-lib.sh
index d1fbc05..7c9ce24 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -926,7 +926,7 @@ test_emacs () {
--eval '(orphan-watchdog $$)'" || return
EMACS_SERVER="$server_name"
# wait until the emacs server is up
-   until test_emacs '()' 2>/dev/null; do
+   until test_emacs '()' >/dev/null 2>/dev/null; do
sleep 1
done
fi
-- 
1.7.7.3



[PATCH 1/4] test: Add `test_emacs_expect_t'.

2012-01-17 Thread David Edmondson
(And one for the list...)

On Tue, 17 Jan 2012 17:09:35 +0400, Dmitry Kurochkin  wrote:
> -1
> 
> This is not what I suggested.  I do not like the approach when a single
> function is used to both declare a subtest and test for result (as
> opposed to test_begin_subtest).  The fact that it is possible to write
> tests in two different ways makes it hard to maintain and improve the
> test framework (one example would be known broken test support).  I
> consider the proper way to write tests to be using the
> test_begin_subtest function.  Other functions are not currently
> deprecated, but I am against adding new code that make the situation
> worse.

Sigh. Okay.

> Also, please consider documenting new functions in README.

Missed that, sorry.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/5f6808fd/attachment.pgp>


[PATCH 2/4] test: Add address cleaning tests.

2012-01-17 Thread David Edmondson
On Tue, 17 Jan 2012 17:11:58 +0400, Dmitry Kurochkin  wrote:
> Since test/ directory is used for all kind of tests not just Emacs
> UI-specific, so I think address-cleaning.* files should be
> emacs-address-cleaning.

Okay.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/1da9e975/attachment.pgp>


[PATCH] NEWS: consistent 2-space indentation

2012-01-17 Thread Tomi Ollila
In NEWS file, indentation for item descriptions is generally 2 spaces
but in a few cases there were 3 or 4 (4 caused different markdown
handling) space indentations. Indentation in those lines are brought
to consistent 2-space indentation.
---
 NEWS |   16 
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/NEWS b/NEWS
index 1161c22..1e561a9 100644
--- a/NEWS
+++ b/NEWS
@@ -133,8 +133,8 @@ Bug-fix release.

 Fix crash in python bindings.

-The python bindings did not call g_type_init, which caused crashes
-for some, but not all users.
+  The python bindings did not call g_type_init, which caused crashes
+  for some, but not all users.

 Notmuch 0.10.1 (2011-11-25)
 ===
@@ -204,8 +204,8 @@ Add keybinding ('c I') for stashing Message-ID's without an 
id: prefix

 Do not query on notmuch-search exit

-   It is harmless to kill the external notmuch process, so the user
-   is no longer interrogated when they interrupt a search.
+  It is harmless to kill the external notmuch process, so the user
+  is no longer interrogated when they interrupt a search.

 Performance
 ---
@@ -234,9 +234,9 @@ mailing list.

 nmbug - share tags with a given prefix

-   nmbug helps maintain a git repo containing all tags with a given
-   prefix (by default "notmuch::"). Tags can be shared by commiting
-   them to git in one location and restoring in another.
+  nmbug helps maintain a git repo containing all tags with a given
+  prefix (by default "notmuch::"). Tags can be shared by commiting
+  them to git in one location and restoring in another.

 Notmuch 0.9 (2011-10-01)
 
@@ -621,7 +621,7 @@ Ruby bindings are now much more complete
s1.union(s2)
s2 -= s1

-   Removed:
+  Removed:
  - len(Messages()) as it exhausted the iterator.
Use len(list(Messages())) or
Query.count_messages() to get the length.
-- 
1.7.7.3



[PATCH 4/4] emacs: Another special case for `notmuch-show-clean-address'.

2012-01-17 Thread David Edmondson
Remove backslashes.
---
 emacs/notmuch-show.el|   14 +-
 test/address-cleaning.el |6 --
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 8b2fbb3..90c9c05 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -248,11 +248,15 @@ unchanged ADDRESS if parsing fails."
(t
(setq p-address address)))

-  ;; Remove outer double quotes. They might be required during
-  ;; transport, but we don't need to see them.
-  (when (and p-name
-(string-match "^\"\\(.*\\)\"$" p-name))
-(setq p-name (match-string 1 p-name)))
+  ;; Remove elements of the mailbox part that are not relevant for
+  ;; display, even if they are required during transport.
+  (when p-name
+   ;; Outer double quotes.
+   (when (string-match "^\"\\(.*\\)\"$" p-name)
+ (setq p-name (match-string 1 p-name)))
+
+   ;; Backslashes.
+   (setq p-name (replace-regexp-in-string "" "" p-name)))

   ;; If the address is 'foo at bar.com ' then show just
   ;; 'foo at bar.com'.
diff --git a/test/address-cleaning.el b/test/address-cleaning.el
index 59e8d92..83d6263 100644
--- a/test/address-cleaning.el
+++ b/test/address-cleaning.el
@@ -20,10 +20,12 @@
   (let* ((input '("?? "
  "foo (at home) "
  "foo [at home] "
- "Foo Bar"))
+ "Foo Bar"
+ "Fred Dibna \\[extraordinaire\\] "))
 (expected '("?? "
 "foo (at home) "
 "foo [at home] "
-"Foo Bar"))
+"Foo Bar"
+"Fred Dibna [extraordinaire] "))
 (output (mapcar #'notmuch-show-clean-address input)))
 (notmuch-test-compare output expected)))
-- 
1.7.7.3



[PATCH 3/4] emacs: Avoid `mail-header-parse-address' in `notmuch-show-clean-address'.

2012-01-17 Thread David Edmondson
`mail-header-parse-address' expects un-decoded mailbox parts, which is
not what we have at this point. Replace it with simple string
deconstruction.
---
 emacs/notmuch-show.el |   48 +++-
 1 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 797f94b..8b2fbb3 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -227,21 +227,43 @@ indentation."
   "Try to clean a single email ADDRESS for display.  Return
 unchanged ADDRESS if parsing fails."
   (condition-case nil
-(let* ((parsed (mail-header-parse-address address))
-  (address (car parsed))
-  (name (cdr parsed)))
-  ;; Remove double quotes. They might be required during transport,
-  ;; but we don't need to see them.
-  (when name
-(setq name (replace-regexp-in-string "\"" "" name)))
+(let (p-name p-address)
+  ;; It would be convenient to use `mail-header-parse-address',
+  ;; but that expects un-decoded mailbox parts, whereas our
+  ;; mailbox parts are already decoded (and hence may contain
+  ;; UTF-8). Given that notmuch should handle most of the awkward
+  ;; cases, some simple string deconstruction should be sufficient
+  ;; here.
+  (cond
+   ;; "User " style.
+   ((string-match "\\(.*\\) <\\(.*\\)>" address)
+   (setq p-name (match-string 1 address)
+ p-address (match-string 2 address)))
+
+   ;; "" style.
+   ((string-match "<\\(.*\\)>" address)
+   (setq p-address (match-string 1 address)))
+
+   ;; Everything else.
+   (t
+   (setq p-address address)))
+  
+  ;; Remove outer double quotes. They might be required during
+  ;; transport, but we don't need to see them.
+  (when (and p-name
+(string-match "^\"\\(.*\\)\"$" p-name))
+(setq p-name (match-string 1 p-name)))
+
   ;; If the address is 'foo at bar.com ' then show just
   ;; 'foo at bar.com'.
-  (when (string= name address)
-(setq name nil))
-
-  (if (not name)
-address
-(concat name " <" address ">")))
+  (when (string= p-name p-address)
+(setq p-name nil))
+
+  ;; If no name results, return just the address.
+  (if (not p-name)
+ p-address
+   ;; Otherwise format the name and address together.
+   (concat p-name " <" p-address ">")))
 (error address)))

 (defun notmuch-show-insert-headerline (headers date tags depth)
-- 
1.7.7.3



[PATCH 2/4] test: Add address cleaning tests.

2012-01-17 Thread David Edmondson
Including some more test framework in test-lib.el.
---
 test/address-cleaning.el |   29 +
 test/address-cleaning.sh |   11 +++
 test/notmuch-test|1 +
 test/test-lib.el |   29 +
 4 files changed, 70 insertions(+), 0 deletions(-)
 create mode 100644 test/address-cleaning.el
 create mode 100755 test/address-cleaning.sh

diff --git a/test/address-cleaning.el b/test/address-cleaning.el
new file mode 100644
index 000..59e8d92
--- /dev/null
+++ b/test/address-cleaning.el
@@ -0,0 +1,29 @@
+(defun notmuch-test-address-cleaning-1 ()
+  (notmuch-test-compare (notmuch-show-clean-address "dme at dme.org")
+   "dme at dme.org"))
+
+(defun notmuch-test-address-cleaning-2 ()
+  (let* ((input '("foo at bar.com"
+ ""
+ "Foo Bar "
+ "foo at bar.com "
+ "\"Foo Bar\" "))
+(expected '("foo at bar.com"
+"foo at bar.com"
+"Foo Bar "
+"foo at bar.com"
+"Foo Bar "))
+(output (mapcar #'notmuch-show-clean-address input)))
+(notmuch-test-compare output expected)))
+
+(defun notmuch-test-address-cleaning-3 ()
+  (let* ((input '("?? "
+ "foo (at home) "
+ "foo [at home] "
+ "Foo Bar"))
+(expected '("?? "
+"foo (at home) "
+"foo [at home] "
+"Foo Bar"))
+(output (mapcar #'notmuch-show-clean-address input)))
+(notmuch-test-compare output expected)))
diff --git a/test/address-cleaning.sh b/test/address-cleaning.sh
new file mode 100755
index 000..7ec011a
--- /dev/null
+++ b/test/address-cleaning.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+test_description="emacs address cleaning"
+. test-lib.sh
+
+for i in 1 2 3; do
+test_emacs_expect_t "notmuch-test-address-clean-$i" \
+'(load "address-cleaning.el") (notmuch-test-address-cleaning-'$i')'
+done
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index d034f99..7768c32 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -53,6 +53,7 @@ TESTS="
   hooks
   argument-parsing
   emacs-test-functions.sh
+  address-cleaning.sh
 "
 TESTS=${NOTMUCH_TESTS:=$TESTS}

diff --git a/test/test-lib.el b/test/test-lib.el
index 3b817c3..cf8a46d 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -20,6 +20,8 @@
 ;;
 ;; Authors: Dmitry Kurochkin 

+(require 'cl)  ;; This code is generally used uncompiled.
+
 ;; `read-file-name' by default uses `completing-read' function to read
 ;; user input.  It does not respect `standard-input' variable which we
 ;; use in tests to provide user input.  So replace it with a plain
@@ -76,3 +78,30 @@ nothing."

 (add-hook-counter 'notmuch-hello-mode-hook)
 (add-hook-counter 'notmuch-hello-refresh-hook)
+
+;; Functions to help when writing tests:
+
+(defun notmuch-test-reporter (output expected)
+  "Report that the `output' does not match the `expected' result."
+  (concat "Expect:\t" (prin1-to-string expected) "\n"
+ "Output:\t" (prin1-to-string output) "\n"))
+
+(defun notmuch-test-unsimilar (output expected)
+  "`output' and `expected' are dissimilar. Show a summary of
+the differences, ignoring similarities."
+  (cond ((and (listp output)
+ (listp expected))
+(apply #'concat (loop for o in output
+  for e in expected
+  if (not (equal o e))
+  collect (notmuch-test-reporter o e
+
+   (t
+;; Catch all case.
+(notmuch-test-reporter output expected
+
+(defun notmuch-test-compare (output expected)
+  "Compare `output' with `expected'. Report any discrepencies."
+  (if (equal output expected)
+  t
+(notmuch-test-unsimilar output expected)))
-- 
1.7.7.3



[PATCH 1/4] test: Add `test_emacs_expect_t'.

2012-01-17 Thread David Edmondson
Add a new test function to allow simpler testing of emacs
functionality.

`test_emacs_expect_t' takes two arguments:
  - the name of the test,
  - some lisp to evaluate.

The test passes if the lisp returns `t', otherwise it fails and the
output is reported to the tester.
---
 test/emacs-test-functions.sh |8 
 test/notmuch-test|1 +
 test/test-lib.sh |   24 
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100755 test/emacs-test-functions.sh

diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh
new file mode 100755
index 000..969cc78
--- /dev/null
+++ b/test/emacs-test-functions.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+test_description="emacs test function sanity"
+. test-lib.sh
+
+test_emacs_expect_t "emacs test function sanity" 't'
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index 6a99ae3..d034f99 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -52,6 +52,7 @@ TESTS="
   python
   hooks
   argument-parsing
+  emacs-test-functions.sh
 "
 TESTS=${NOTMUCH_TESTS:=$TESTS}

diff --git a/test/test-lib.sh b/test/test-lib.sh
index 7c9ce24..15da973 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -503,6 +503,30 @@ test_expect_equal_file ()
 fi
 }

+test_emacs_expect_t () {
+   test "$#" = 2 || error "bug in the test script: not 2 parameters to 
test_emacs_expect_t"
+   test_reset_state_
+   if ! test_skip "$1"
+   then
+   # We cannot call 'test_emacs' in a subshell, because
+   # the setting of EMACS_SERVER would not persist
+   # throughout a sequence of tests, so we use a
+   # temporary file.
+   tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi
+   output="$tmp/test_emacs_output.$$"
+   test_emacs "$2" >"${output}"
+   result=$(cat "${output}")
+   rm -f "${output}"
+
+   if [ "$result" == t ]
+   then
+   test_ok_ "$1"
+   else
+   test_failure_ "$1" "$(eval printf ${result})"
+   fi
+   fi
+}
+
 NOTMUCH_NEW ()
 {
 notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* 
total file'
-- 
1.7.7.3



emacs based tests, version 3

2012-01-17 Thread David Edmondson
Taking Dmitry's suggestions on board. The end result does indeed feel
better, thanks!

[PATCH 1/4] test: Add `test_emacs_expect_t'.
[PATCH 2/4] test: Add address cleaning tests.
[PATCH 3/4] emacs: Avoid `mail-header-parse-address' in
[PATCH 4/4] emacs: Another special case for


[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Adrian Perez
\": [");
> > +
> > +if (!siglist) {
> > +   printf ("]");
> > +   return;
> > + }
> > +
> > +void *ctx_quote = talloc_new (NULL);
> > +int i;
> > +for (i = 0; i < g_mime_signature_list_length (siglist); ++i) {
> 
> Style nit: notmuch uses i++.
> 
> > +   GMimeSignature *signature = g_mime_signature_list_get_signature 
> > (siglist, i);
> > +
> > +   if (i > 0)
> > +   printf (", ");
> > +
> > +   printf ("{");
> > +
> > +   /* status */
> > +   GMimeSignatureStatus status = g_mime_signature_get_status (signature);
> > +   printf ("\"status\": %s",
> > +   json_quote_str (ctx_quote,
> > +   signature_status_to_string (status)));
> > +
> > +   GMimeCertificate *certificate = g_mime_signature_get_certificate 
> > (signature);
> > +   if (status == GMIME_SIGNATURE_STATUS_GOOD)
> > +   {
> 
> Style nit: break after brace.
> 
> (Presumably this is copied from the existing
> format_part_sigstatus_json, but since it's technically new code
> there's no reason not to fix these up.)
> 
> > +   if (certificate)
> > +   printf (", \"fingerprint\": %s", json_quote_str (ctx_quote, 
> > g_mime_certificate_get_fingerprint (certificate)));
> > +   /* these dates are seconds since the epoch; should we
> > +* provide a more human-readable format string? */
> > +   time_t created = g_mime_signature_get_created (signature);
> > +   if (created != -1)
> > +   printf (", \"created\": %d", (int) created);
> > +   time_t expires = g_mime_signature_get_expires (signature);
> > +   if (expires > 0)
> > +   printf (", \"expires\": %d", (int) expires);
> 
> Is it intentional that the two above checks are different?  I would
> think the second should be expires != -1.

Yes, it should check for ?expires != -1?. Also, wouldn't it be needed to
cast do ?expires != (time_t) -1? to avoid compiler warnings? (time_t may
be different from int.)

> > +   /* output user id only if validity is FULL or ULTIMATE. */
> > +   /* note that gmime is using the term "trust" here, which
> > +* is WRONG.  It's actually user id "validity". */
> > +   if (certificate)
> > +   {
> 
> Break after brace.
> 
> > +   const char *name = g_mime_certificate_get_name (certificate);
> > +   GMimeCertificateTrust trust = g_mime_certificate_get_trust 
> > (certificate);
> > +   if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == 
> > GMIME_CERTIFICATE_TRUST_ULTIMATE))
> > +   printf (", \"userid\": %s", json_quote_str (ctx_quote, 
> > name));
> > +   }
> > +   } else if (certificate) {
> > +   const char *key_id = g_mime_certificate_get_key_id (certificate);
> > +   if (key_id)
> > +   printf (", \"keyid\": %s", json_quote_str (ctx_quote, key_id));
> > +   }
> > +
> > +   GMimeSignatureError errors = g_mime_signature_get_errors (signature);
> > +   if (errors != GMIME_SIGNATURE_ERROR_NONE) {
> > +   printf (", \"errors\": %x", errors);
> 
> This should be %d (I would say 0x%x, but JSON doesn't support hex
> literals).  I see this bug came from the original
> format_part_sigstatus_json.  Maybe there should be a quick patch
> before this one that fixes the source of the bug?
> 
> > +   }
> > +
> > +   printf ("}");
> > + }
> > +
> > +printf ("]");
> > +
> > +talloc_free (ctx_quote);
> > +}
> > +#else
> >  static void
> >  format_part_sigstatus_json (const GMimeSignatureValidity* validity)
> >  {
> > @@ -652,6 +741,7 @@ format_part_sigstatus_json (const 
> > GMimeSignatureValidity* validity)
> >  
> >  talloc_free (ctx_quote);
> >  }
> > +#endif
> >  
> >  static void
> >  format_part_content_json (GMimeObject *part)
> > @@ -990,13 +1080,20 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
> >(STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
> > if (params.cryptoctx == NULL) {
> > +#ifdef GMIME_26
> > +   /* TODO: GMimePasswordRequestFunc */
> > +   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(NULL, 
> > "gpg")))
> > +#else
> > GMimeSession* session = g_object_new(g_mime_session_get_type(), 
> > NULL);
> > if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
> > "gpg")))
> > +#endif
> > fprintf (stderr, "Failed to construct gpg context.\n");
> > else
> > 
> > g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, 
> > FALSE);
> > +#ifndef GMIME_26
> > g_object_unref (session);
> > session = NULL;
> > +#endif
> > }
> > if (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)
> > params.decrypt = 1;
> > diff --git a/show-message.c b/show-message.c
> > index 8768889..65269fd 100644
> > --- a/show-message.c
> > +++ b/show-message.c
> > @@ -48,7 +48,11 @@ show_message_part (mime_node_t *node,
> > format->part_encstatus (node->decrypt_success);
> >  
> >  if (node->verify_attempted && format->part_sigstatus)
> > +#ifdef GMIME_26
> > +   format->part_sigstatus (node->sig_list);
> > +#else
> > format->part_sigstatus (node->sig_validity);
> > +#endif
> >  
> >  format->part_content (part);
> >  

-- 
Adrian Perez  - Sent from my toaster
Igalia - Free Software Engineering
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/84d3b127/attachment.pgp>


[PATCH 2/3] emacs: whitespace-cleanup and indent-region for emacs/*.el files

2012-01-17 Thread Tomi Ollila
On Mon, 16 Jan 2012 23:32:00 -0500, Austin Clements  wrote:
> Cleanup is the type of pain that should only be suffered once, so I'd
> be much happier with this if there was an accompanying git hook that
> prevented more mis-formatted code from slipping in.

We'd need a script to be called from .git/hooks/pre-commit to do
extra checking; developer needs first activate this pre-commit
and then add call to our checking routine. Imagine the amount
of false positives this hook starts to generate...

... but. developer can run 'git commit --no-verify' ...aargh no;
I guess if pre-commit hook fails, commit-msg hook is not run
and this is bypassed; maybe NO_FORMATCHECK_HOOK=1 git commit ...
is the answer.

But what we at least need is Guidelines document that states 
these formatting issues clearly and precicely. Surely 
self-respecting programmers understands to follow there (and soon 
adjusts their workflow -- i.e. activate/run these checkers
after list response).

> Quoth Tomi Ollila on Jan 16 at 11:04 am:
> > diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
> > index 00ed589..7b63348 100644
> > --- a/emacs/notmuch-lib.el
> > +++ b/emacs/notmuch-lib.el
> > @@ -143,7 +143,7 @@ The result is a new function which does the same as 
> > FUN, except that
> >  the first N arguments are fixed at the values with which this function
> >  was called."
> > (lexical-let ((fun fun) (args1 args))
> > - (lambda ( args2) (apply fun (append args1 args2))
> > +   (lambda ( args2) (apply fun (append args1 args2))
> 
> Ack.  What happened here?  This shows up in at least one other place,
> too.  I'm betting you need to load cl in some form to get the
> indentation rule for lexical-let.

Yes, thanks. (require 'cl) fixes that. I'll mark this and the RFC patch
(of batch-tools.el) obsolete. 

Tomi


[PATCH 2/3] emacs: whitespace-cleanup and indent-region for emacs/*.el files

2012-01-17 Thread Austin Clements
Quoth Tomi Ollila on Jan 17 at 12:46 pm:
> On Mon, 16 Jan 2012 23:32:00 -0500, Austin Clements  
> wrote:
> > Cleanup is the type of pain that should only be suffered once, so I'd
> > be much happier with this if there was an accompanying git hook that
> > prevented more mis-formatted code from slipping in.
> 
> We'd need a script to be called from .git/hooks/pre-commit to do
> extra checking; developer needs first activate this pre-commit
> and then add call to our checking routine. Imagine the amount
> of false positives this hook starts to generate...

It's unfortunate (but sensible) that git doesn't provide an automatic
way to set up verify scripts like this, but that doesn't mean we can't
make it easy.  Put a script in devel (or whatever it winds up being
called) that can be sourced from the pre-commit hook and then mention
this in HACKING.

Why it would generate false positives, assuming the cleanup goes in at
the same time the hook goes in (or the script is somehow clever enough
to only check changed lines)?

> ... but. developer can run 'git commit --no-verify' ...aargh no;
> I guess if pre-commit hook fails, commit-msg hook is not run
> and this is bypassed; maybe NO_FORMATCHECK_HOOK=1 git commit ...
> is the answer.

Maybe the script could generate a warning/prompt, rather than
preventing the commit altogether?

> But what we at least need is Guidelines document that states 
> these formatting issues clearly and precicely. Surely 
> self-respecting programmers understands to follow there (and soon 
> adjusts their workflow -- i.e. activate/run these checkers
> after list response).

I think the guidelines for elisp are pretty well known.  I agree that
we need such a document for the C/C++ code.  I started writing one a
while ago, but other things took over before I got very far.


Infinite loop in emacs interface

2012-01-17 Thread Aaron Ecay
Rodney,

After converting the mbox file to Maildir and adding it to my mailstore,
I cannot reproduce the loop.  (The versions of notmuch and emacs I used
are close to the ones you have, but not an exact match, so it may be
something subtle about those versions.  I can investigate
more carefully if it seems like this is the case.)

If you do:
M-x set-variable RET debug-on-quit RET t RET
then trigger the loop and press C-g, you should get a buffer showing a
backtrace of the lisp stack.  What does that say?

Thanks,

-- 
Aaron Ecay


[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Adrian Perez

Hi,

On Tue, 17 Jan 2012 00:56:39 +0100, Thomas Jost  
wrote:

> There are lots of API changes in gmime 2.6 crypto handling. By adding
> preprocessor directives, it is however possible to add gmime 2.6 compatibility
> while preserving compatibility with gmime 2.4 too.

This approach is better than just dropping support for 2.4 (as my patch
does), so I would favor integrating this one instead of mine :D

Br.

-- 
Adrian Perez  - Sent from my toaster
Igalia - Free Software Engineering
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/cad6351f/attachment.pgp>


[PATCH 1/6] emacs: break up notmuch-show-archive-thread-internal into two generally useful functions

2012-01-17 Thread Jameson Graef Rollins
On Tue, 17 Jan 2012 15:10:40 -0500, Aaron Ecay  wrote:
> This should be a docstring instead of a comment.  (This applies equally
> to the old version)

We're not currently in the habit of adding doc strings for
non-interactive programs.  Do we need to go down that route?

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/20120117/cc1ed564/attachment.pgp>


[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
There are lots of API changes in gmime 2.6 crypto handling. By adding
preprocessor directives, it is however possible to add gmime 2.6 compatibility
while preserving compatibility with gmime 2.4 too.

This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".

This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
fails (signature verification with signer key unavailable) but this will be hard
to fix since the new API does not report the reason why a signature verification
fails (other than the human-readable error message).
---
 mime-node.c  |   56 ++--
 notmuch-client.h |   28 +++-
 notmuch-reply.c  |7 
 notmuch-show.c   |   95 ++
 show-message.c   |4 ++
 5 files changed, 185 insertions(+), 5 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d26bb44..e575e1c 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -33,7 +33,11 @@ typedef struct mime_node_context {
 GMimeMessage *mime_message;

 /* Context provided by the caller. */
+#ifdef GMIME_26
+GMimeCryptoContext *cryptoctx;
+#else
 GMimeCipherContext *cryptoctx;
+#endif
 notmuch_bool_t decrypt;
 } mime_node_context_t;

@@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)

 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
-   GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,
-   mime_node_t **root_out)
+#ifdef GMIME_26
+   GMimeCryptoContext *cryptoctx,
+#else
+   GMimeCipherContext *cryptoctx,
+#endif
+   notmuch_bool_t decrypt, mime_node_t **root_out)
 {
 const char *filename = notmuch_message_get_filename (message);
 mime_node_context_t *mctx;
@@ -112,12 +120,21 @@ DONE:
 return status;
 }

+#ifdef GMIME_26
+static int
+_signature_list_free (GMimeSignatureList **proxy)
+{
+g_object_unref (*proxy);
+return 0;
+}
+#else
 static int
 _signature_validity_free (GMimeSignatureValidity **proxy)
 {
 g_mime_signature_validity_free (*proxy);
 return 0;
 }
+#endif

 static mime_node_t *
 _mime_node_create (const mime_node_t *parent, GMimeObject *part)
@@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
GMimeMultipartEncrypted *encrypteddata =
GMIME_MULTIPART_ENCRYPTED (part);
node->decrypt_attempted = TRUE;
+#ifdef GMIME_26
+   GMimeDecryptResult *decrypt_result = NULL;
+   node->decrypted_child = g_mime_multipart_encrypted_decrypt
+   (encrypteddata, node->ctx->cryptoctx, _result, );
+#else
node->decrypted_child = g_mime_multipart_encrypted_decrypt
(encrypteddata, node->ctx->cryptoctx, );
+#endif
if (node->decrypted_child) {
-   node->decrypt_success = node->verify_attempted = TRUE;
+   node->decrypt_success = node->verify_attempted =TRUE;
+#ifdef GMIME_26
+   /* This may be NULL if the part is not signed. */
+   node->sig_list = g_mime_decrypt_result_get_signatures 
(decrypt_result);
+#else
node->sig_validity = 
g_mime_multipart_encrypted_get_signature_validity (encrypteddata);
+#endif
} else {
fprintf (stderr, "Failed to decrypt part: %s\n",
 (err ? err->message : "no error explanation given"));
@@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
 "(must be exactly 2)\n",
 node->nchildren);
} else {
+#ifdef GMIME_26
+   GMimeSignatureList *sig_list = g_mime_multipart_signed_verify
+   (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, );
+   node->verify_attempted = TRUE;
+   node->sig_list = sig_list;
+
+   if (!sig_list)
+   fprintf (stderr, "Failed to verify signed part: %s\n",
+(err ? err->message : "no error explanation given"));
+#else
/* For some reason the GMimeSignatureValidity returned
 * here is not a const (inconsistent with that
 * returned by
@@ -200,12 +238,24 @@ _mime_node_create (const mime_node_t *parent, GMimeObject 
*part)
*proxy = sig_validity;
talloc_set_destructor (proxy, _signature_validity_free);
}
+#endif
}
 }

+#ifdef GMIME_26
+/* sig_list may be created in both above cases, so we need to
+ * cleanly handle it here. */
+if (node->sig_list) {
+   GMimeSignatureList **proxy =
+   talloc (node, GMimeSignatureList *);
+   *proxy = node->sig_list;
+   talloc_set_destructor (proxy, _signature_list_free);
+}
+#else
 if (node->verify_attempted && !node->sig_validity)
fprintf (stderr, "Failed to verify signed 

[PATCH v2 1/2] show: don't use hex literals in JSON output

2012-01-17 Thread Thomas Jost
JSON does not support hex literals (0x..) so numbers must be formatted as %d
instead of %x.
---
 notmuch-show.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index d14dac9..91f566c 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -641,7 +641,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* 
validity)
printf (", \"keyid\": %s", json_quote_str (ctx_quote, 
signer->keyid));
}
if (signer->errors != GMIME_SIGNER_ERROR_NONE) {
-   printf (", \"errors\": %x", signer->errors);
+   printf (", \"errors\": %d", signer->errors);
}

printf ("}");
-- 
1.7.8.3



[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Thomas Jost
if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == 
> > GMIME_CERTIFICATE_TRUST_ULTIMATE))
> > +   printf (", \"userid\": %s", json_quote_str (ctx_quote, 
> > name));
> > +   }
> > +   } else if (certificate) {
> > +   const char *key_id = g_mime_certificate_get_key_id (certificate);
> > +   if (key_id)
> > +   printf (", \"keyid\": %s", json_quote_str (ctx_quote, key_id));
> > +   }
> > +
> > +   GMimeSignatureError errors = g_mime_signature_get_errors (signature);
> > +   if (errors != GMIME_SIGNATURE_ERROR_NONE) {
> > +   printf (", \"errors\": %x", errors);
> 
> This should be %d (I would say 0x%x, but JSON doesn't support hex
> literals).  I see this bug came from the original
> format_part_sigstatus_json.  Maybe there should be a quick patch
> before this one that fixes the source of the bug?

Right. I'll add a first patch to change this in the original 
format_part_sigstatus_json.

> 
> > +   }
> > +
> > +   printf ("}");
> > + }
> > +
> > +printf ("]");
> > +
> > +talloc_free (ctx_quote);
> > +}
> > +#else
> >  static void
> >  format_part_sigstatus_json (const GMimeSignatureValidity* validity)
> >  {
> > @@ -652,6 +741,7 @@ format_part_sigstatus_json (const 
> > GMimeSignatureValidity* validity)
> >  
> >  talloc_free (ctx_quote);
> >  }
> > +#endif
> >  
> >  static void
> >  format_part_content_json (GMimeObject *part)
> > @@ -990,13 +1080,20 @@ notmuch_show_command (void *ctx, unused (int argc), 
> > unused (char *argv[]))
> > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
> >(STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
> > if (params.cryptoctx == NULL) {
> > +#ifdef GMIME_26
> > +   /* TODO: GMimePasswordRequestFunc */
> > +   if (NULL == (params.cryptoctx = g_mime_gpg_context_new(NULL, 
> > "gpg")))
> > +#else
> > GMimeSession* session = g_object_new(g_mime_session_get_type(), 
> > NULL);
> > if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, 
> > "gpg")))
> > +#endif
> > fprintf (stderr, "Failed to construct gpg context.\n");
> > else
> > 
> > g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, 
> > FALSE);
> > +#ifndef GMIME_26
> > g_object_unref (session);
> > session = NULL;
> > +#endif
> > }
> > if (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)
> > params.decrypt = 1;
> > diff --git a/show-message.c b/show-message.c
> > index 8768889..65269fd 100644
> > --- a/show-message.c
> > +++ b/show-message.c
> > @@ -48,7 +48,11 @@ show_message_part (mime_node_t *node,
> > format->part_encstatus (node->decrypt_success);
> >  
> >  if (node->verify_attempted && format->part_sigstatus)
> > +#ifdef GMIME_26
> > +   format->part_sigstatus (node->sig_list);
> > +#else
> > format->part_sigstatus (node->sig_validity);
> > +#endif
> >  
> >  format->part_content (part);
> >  

-- 
Thomas/Schnouki
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/530ee4d7/attachment.pgp>


[PATCH] Add pseudo-compatibility with gmime 2.6

2012-01-17 Thread Tim Stoakes
Thomas Jost(schnouki at schnouki.net)@170112-00:56:
> There are lots of API changes in gmime 2.6 crypto handling. By adding
> preprocessor directives, it is however possible to add gmime 2.6 compatibility
> while preserving compatibility with gmime 2.4 too.
> 
> This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info".
> 
> This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the
> crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test
> fails (signature verification with signer key unavailable) but this will be 
> hard
> to fix since the new API does not report the reason why a signature 
> verification
> fails (other than the human-readable error message).

+1 from me.

I literally just coded up a similar patch, and the first email I see
with the newly compiled notmuch is this one. I've now tried Thomas's
(better) patch with gmime-2.6.4 and notmuch
7ddd849015759a329bf8fef8c8b5a93359408962, and can confirm it works fine
for me. This build breakage is otherwise quite painful.

Thanks Thomas.

Tim

-- 
Tim Stoakes


[PATCH 3/3] emacs: add delete key bindings for search and show mode.

2012-01-17 Thread Jameson Graef Rollins
This mimics the archiving keys ('a' and 'A').
---
 emacs/notmuch-show.el |2 ++
 emacs/notmuch.el  |1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 141241d..f0259d5 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -945,6 +945,8 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
(define-key map "-" 'notmuch-show-remove-tag)
(define-key map "+" 'notmuch-show-add-tag)
(define-key map "x" 'notmuch-show-archive-thread-then-exit)
+   (define-key map "d" 'notmuch-show-delete-message-then-next)
+   (define-key map "D" 'notmuch-show-delete-thread-then-next)
(define-key map "a" 'notmuch-show-archive-message-then-next)
(define-key map "A" 'notmuch-show-archive-thread-then-next)
(define-key map "N" 'notmuch-show-next-message)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 2acb31b..9f1b1ca 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -225,6 +225,7 @@ For a mouse binding, return nil."
 (define-key map "f" 'notmuch-search-filter)
 (define-key map [mouse-1] 'notmuch-search-show-thread)
 (define-key map "*" 'notmuch-search-operate-all)
+(define-key map "d" 'notmuch-search-delete-thread)
 (define-key map "a" 'notmuch-search-archive-thread)
 (define-key map "-" 'notmuch-search-remove-tag)
 (define-key map "+" 'notmuch-search-add-tag)
-- 
1.7.7.3



[PATCH 2/3] emacs: message/thread deletion by adding "deleted" tag

2012-01-17 Thread Jameson Graef Rollins
---
 emacs/notmuch-show.el |   46 ++
 emacs/notmuch.el  |8 
 2 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index c1d721e..141241d 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1506,6 +1506,52 @@ removed)."
   (notmuch-show-archive-message)
   (notmuch-show-next-open-message t))

+(defun notmuch-show-delete-thread ( undelete)
+  "Delete each message in thread.
+
+Delete each message currently shown by adding the \"deleted\" tag
+to each.  If a prefix argument is given, the messages will be
+\"undeleted\" (ie. the \"deleted\" tag will be removed instead of
+added).
+
+Note: This command is safe from any race condition of new messages
+being delivered to the same thread. It does not archive the
+entire thread, but only the messages shown in the current
+buffer."
+  (interactive)
+  (if undelete
+  (notmuch-show-remove-tag-thread "deleted")
+(notmuch-show-add-tag-thread "deleted")))
+
+(defun notmuch-show-delete-thread-then-next ()
+  "Delete each message in thread, then show next thread from search."
+  (interactive)
+  (notmuch-show-delete-thread)
+  (notmuch-show-next-thread t))
+
+(defun notmuch-show-delete-thread-then-exit ()
+  "Delete each message in thread, then exit back to search results."
+  (interactive)
+  (notmuch-show-delete-thread)
+  (notmuch-show-next-thread))
+
+(defun notmuch-show-delete-message ( undelete)
+  "Delete the current message (add \"deleted\" tag).
+
+If a prefix argument is given, the message will be
+\"undeleted\" (ie. the \"deleted\" tag will be removed instead of
+added)."
+  (interactive)
+  (if undelete
+  (notmuch-show-remove-tag "deleted")
+(notmuch-show-add-tag "deleted")))
+
+(defun notmuch-show-delete-message-then-next ()
+  "Archive the current message, then show next thread from search."
+  (interactive)
+  (notmuch-show-delete-message)
+  (notmuch-show-next-open-message t))
+
 (defun notmuch-show-stash-cc ()
   "Copy CC field of current message to kill-ring."
   (interactive)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 67ecd3a..2acb31b 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -619,6 +619,14 @@ This function advances the next thread when finished."
   (notmuch-search-remove-tag-thread "inbox")
   (notmuch-search-next-thread))

+(defun notmuch-search-delete-thread ()
+  "Delete the currently selected thread (add \"deleted\" tag).
+
+This function advances the next thread when finished."
+  (interactive)
+  (notmuch-search-add-tag-thread "deleted")
+  (notmuch-search-next-thread))
+
 (defvar notmuch-search-process-filter-data nil
   "Data that has not yet been processed.")
 (make-variable-buffer-local 'notmuch-search-process-filter-data)
-- 
1.7.7.3



[PATCH 1/3] emacs: modify help message for notmuch-search-line-faces to reflect preferred "deleted" tag name.

2012-01-17 Thread Jameson Graef Rollins
No functional change here.  The help message previously referred to
the "delete" tag, but "deleted" is now preferred, so hopefully this
will reduce any potential confusion.
---
 emacs/notmuch.el |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index e4bca51..67ecd3a 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -660,12 +660,12 @@ This function advances the next thread when finished."
 Here is an example of how to color search results based on tags.
  (the following text would be placed in your ~/.emacs file):

- (setq notmuch-search-line-faces '((\"delete\" . (:foreground \"red\"
+ (setq notmuch-search-line-faces '((\"deleted\" . (:foreground \"red\"
  :background \"blue\"))
(\"unread\" . (:foreground \"green\"

 The attributes defined for matching tags are merged, with later
-attributes overriding earlier. A message having both \"delete\"
+attributes overriding earlier. A message having both \"deleted\"
 and \"unread\" tags with the above settings would have a green
 foreground and blue background."
   :type '(alist :key-type (string) :value-type (custom-face-edit))
-- 
1.7.7.3



on deleting messages

2012-01-17 Thread Jameson Graef Rollins
Now that Austin's excellent tag exclusion patch set [0] has been pushed,
the question remains if we want to support any delete-handling key
bindings in emacs.

Based on the show-mode improvements I recently sent [1], the following
patch set implements thread and message delete keys.

This is the last I'm going to comment on this issue.  If we don't want
to support this, we should put together something on the wiki that
states we don't want to support it and that users should just bind it
themselves (with a nice explanation how), so that we can try to reduce
the number of future patches on the issue.

Given the number of patches we've had on this issue, though, it's clear
that a lot of people expect this functionality, so we may want to
seriously consider supporting it.  Given Austin's tag exclusion stuff,
and the fact that "deleted" tags are excluded by default, we now have
the functionality that Carl originally wanted to see, so it's not so
unreasonable to support this functionality anymore.

jamie.

[0] id:"1326496024-14403-1-git-send-email-amdragon at mit.edu"
[1] id:"871uqy19yo.fsf at servo.finestructure.net"
-- 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/20120117/b08ec4bb/attachment.pgp>


[PATCH] emacs: have notmuch-search-archive-thread use -next-thread function

2012-01-17 Thread Jameson Graef Rollins
Use this standard function, to keep thread navigation in one place.
---
 emacs/notmuch.el |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index ef4dcc7..e4bca51 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -617,7 +617,7 @@ thread or threads in the current region."
 This function advances the next thread when finished."
   (interactive)
   (notmuch-search-remove-tag-thread "inbox")
-  (forward-line))
+  (notmuch-search-next-thread))

 (defvar notmuch-search-process-filter-data nil
   "Data that has not yet been processed.")
-- 
1.7.7.3



[PATCH] emacs: fix archive thread/message function documentation.

2012-01-17 Thread Jameson Graef Rollins
This removes an inaccuracy in the thread archiving function, and adds
a clarification to the message archiving function.
---
Late catch on some documentation inaccuracies.  Apologies.

 emacs/notmuch-show.el |   11 ---
 1 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index c488e6a..c1d721e 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1463,13 +1463,10 @@ argument, hide all of the messages."
 (defun notmuch-show-archive-thread ( unarchive)
   "Archive each message in thread.

-If a prefix argument is given, the messages will be
-\"unarchived\" (ie. the \"inbox\" tag will be added instead of
-removed).
-
 Archive each message currently shown by removing the \"inbox\"
-tag from each. Then kill this buffer and show the next thread
-from the search from which this thread was originally shown.
+tag from each.  If a prefix argument is given, the messages will
+be \"unarchived\" (ie. the \"inbox\" tag will be added instead of
+removed).

 Note: This command is safe from any race condition of new messages
 being delivered to the same thread. It does not archive the
@@ -1493,7 +1490,7 @@ buffer."
   (notmuch-show-next-thread))

 (defun notmuch-show-archive-message ( unarchive)
-  "Archive the current message.
+  "Archive the current message (remove \"inbox\" tag).

 If a prefix argument is given, the message will be
 \"unarchived\" (ie. the \"inbox\" tag will be added instead of
-- 
1.7.7.3



[PATCH] fix .gitignore for gzipped man pages

2012-01-17 Thread Jameson Graef Rollins
+1.

jamie.


[PATCH 6/6] emacs: modify the default show-mode key bindings for archiving

2012-01-17 Thread Jameson Graef Rollins
This changes the default key bindings for the 'a' key in notmuch-show
mode.  Instead of archiving the entire thread, it now just archives
the current message, and then advance to the next open message
(archive-message-then-next).  'A' is now bound to the previous
archive-thread-then-next function.
---
 emacs/notmuch-show.el |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 21eadbe..c488e6a 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -945,7 +945,8 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
(define-key map "-" 'notmuch-show-remove-tag)
(define-key map "+" 'notmuch-show-add-tag)
(define-key map "x" 'notmuch-show-archive-thread-then-exit)
-   (define-key map "a" 'notmuch-show-archive-thread-then-next)
+   (define-key map "a" 'notmuch-show-archive-message-then-next)
+   (define-key map "A" 'notmuch-show-archive-thread-then-next)
(define-key map "N" 'notmuch-show-next-message)
(define-key map "P" 'notmuch-show-previous-message)
(define-key map "n" 'notmuch-show-next-open-message)
-- 
1.7.7.3



[PATCH 5/6] emacs: use pop-at-end functionality in show-archive-message-then-next function

2012-01-17 Thread Jameson Graef Rollins
This provides a smoother message processing flow by reducing the
number of key presses needed for these common operations.
---
 emacs/notmuch-show.el |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 6b2e6e9..21eadbe 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1506,7 +1506,7 @@ removed)."
   "Archive the current message, then show next thread from search."
   (interactive)
   (notmuch-show-archive-message)
-  (notmuch-show-next-open-message))
+  (notmuch-show-next-open-message t))

 (defun notmuch-show-stash-cc ()
   "Copy CC field of current message to kill-ring."
-- 
1.7.7.3



[PATCH 4/6] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end

2012-01-17 Thread Jameson Graef Rollins
This will allow for keybindings that achieve a smoother message
processing flow by reducing the number of key presses needed for most
common operations.
---
 emacs/notmuch-show.el |   12 +---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 207949c..6b2e6e9 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1270,17 +1270,23 @@ any effects from previous calls to
   (notmuch-show-mark-read)
   (notmuch-show-message-adjust))

-(defun notmuch-show-next-open-message ()
+(defun notmuch-show-next-open-message ( pop-at-end)
   "Show the next message."
   (interactive)
-  (let (r)
+  (let ((r)
+   (parent-buffer notmuch-show-parent-buffer))
 (while (and (setq r (notmuch-show-goto-message-next))
(not (notmuch-show-message-visible-p
 (if r
(progn
  (notmuch-show-mark-read)
  (notmuch-show-message-adjust))
-  (goto-char (point-max)
+  (if (and parent-buffer pop-at-end)
+ (progn
+   (kill-this-buffer)
+   (switch-to-buffer parent-buffer)
+   (forward-line 1))
+   (goto-char (point-max))

 (defun notmuch-show-previous-open-message ()
   "Show the previous message."
-- 
1.7.7.3



[PATCH 3/6] emacs: add message archiving functions

2012-01-17 Thread Jameson Graef Rollins
This adds two new message archiving functions that parallel the thread
archiving functions: notmuch-show-archive-message{,-then-next}.  The
former also takes a prefix argument to unarchive the message (ie. put
back in inbox).
---
 emacs/notmuch-show.el |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index ee9ef62..207949c 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1485,6 +1485,23 @@ buffer."
   (notmuch-show-archive-thread)
   (notmuch-show-next-thread))

+(defun notmuch-show-archive-message ( unarchive)
+  "Archive the current message.
+
+If a prefix argument is given, the message will be
+\"unarchived\" (ie. the \"inbox\" tag will be added instead of
+removed)."
+  (interactive)
+  (if unarchive
+  (notmuch-show-add-tag "inbox")
+(notmuch-show-remove-tag "inbox")))
+
+(defun notmuch-show-archive-message-then-next ()
+  "Archive the current message, then show next thread from search."
+  (interactive)
+  (notmuch-show-archive-message)
+  (notmuch-show-next-open-message))
+
 (defun notmuch-show-stash-cc ()
   "Copy CC field of current message to kill-ring."
   (interactive)
-- 
1.7.7.3



[PATCH 2/6] emacs: break out thread navigation from notmuch-show-archive-thread

2012-01-17 Thread Jameson Graef Rollins
This function is now just for archiving the current thread.  A new
function is created to archive-then-next.  The 'a' key binding is
updated accordingly.

This will allow people to bind to the simple thread archiving function
without the extra navigation.  The archive-thread function now also
takes a prefix to unarchive the current thread (ie. put the whole
thread back in the inbox).
---
 emacs/notmuch-show.el |   23 +--
 1 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 3625afd..ee9ef62 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -945,7 +945,7 @@ thread id.  If a prefix is given, crypto processing is 
toggled."
(define-key map "-" 'notmuch-show-remove-tag)
(define-key map "+" 'notmuch-show-add-tag)
(define-key map "x" 'notmuch-show-archive-thread-then-exit)
-   (define-key map "a" 'notmuch-show-archive-thread)
+   (define-key map "a" 'notmuch-show-archive-thread-then-next)
(define-key map "N" 'notmuch-show-next-message)
(define-key map "P" 'notmuch-show-previous-message)
(define-key map "n" 'notmuch-show-next-open-message)
@@ -1200,7 +1200,7 @@ thread from the search from which this thread was 
originally
 shown."
   (interactive)
   (if (notmuch-show-advance)
-  (notmuch-show-archive-thread)))
+  (notmuch-show-archive-thread-then-next)))

 (defun notmuch-show-rewind ()
   "Backup through the thread, (reverse scrolling compared to 
\\[notmuch-show-advance-and-archive]).
@@ -1453,8 +1453,12 @@ argument, hide all of the messages."
  (if show-next
  (notmuch-search-show-thread))

-(defun notmuch-show-archive-thread ()
-  "Archive each message in thread, then show next thread from search.
+(defun notmuch-show-archive-thread ( unarchive)
+  "Archive each message in thread.
+
+If a prefix argument is given, the messages will be
+\"unarchived\" (ie. the \"inbox\" tag will be added instead of
+removed).

 Archive each message currently shown by removing the \"inbox\"
 tag from each. Then kill this buffer and show the next thread
@@ -1465,13 +1469,20 @@ being delivered to the same thread. It does not archive 
the
 entire thread, but only the messages shown in the current
 buffer."
   (interactive)
-  (notmuch-show-remove-tag-thread "inbox")
+  (if unarchive
+  (notmuch-show-add-tag-thread "inbox")
+(notmuch-show-remove-tag-thread "inbox")))
+
+(defun notmuch-show-archive-thread-then-next ()
+  "Archive each message in thread, then show next thread from search."
+  (interactive)
+  (notmuch-show-archive-thread)
   (notmuch-show-next-thread t))

 (defun notmuch-show-archive-thread-then-exit ()
   "Archive each message in thread, then exit back to search results."
   (interactive)
-  (notmuch-show-remove-tag-thread "inbox")
+  (notmuch-show-archive-thread)
   (notmuch-show-next-thread))

 (defun notmuch-show-stash-cc ()
-- 
1.7.7.3



show-mode message/thread archiving improvements

2012-01-17 Thread Jameson Graef Rollins
I have reworked the show-mode message/thread archiving improvements from
two now-obsolete patch sets:

id:"1325975294-646-1-git-send-email-jrollins at finestructure.net"
id:"1325986015-22510-1-git-send-email-jrollins at finestructure.net"

All the "delete" stuff has been removed from this series, and I just
focus on improving the functions associated with message and thread
tagging, archiving, and navigation.  I also incorporated some good
suggestions from Aaron Ecay to make things "lispier".

The first five patches should be non-controversial and just improve the
available functions without changing any visible behavior.  Together
they make it much easier for users to create useful custom key bindings
to achieve custom tagging and navigation operations.

The last patch changes the default keybind for the 'a' key to archive
just the current message, and not the entire thread.  In my opinion this
is a *much* more sensible binding for this key.  I actually rebound to
this immediately after I started using notmuch long ago.  It also adds a
new 'A' that performs the old function to archive the entire thread and
move on.

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/20120117/eaf19b20/attachment.pgp>


how about message-citation-line-format (was: Re: [PATCH v2 5/4] emacs: Add customization for the first line of quotes.)

2012-01-17 Thread Adam Wolfe Gordon
On Tue, Jan 17, 2012 at 00:17, Gregor Zattler  wrote:
> I really missed this feature in notmuch. ?There is already
> message-citation-line-format which is part of message mode or
> gnus and is not used in notmuch. ?Wouldn't it be more consistent
> to reuse this?

Glad to hear someone would use the feature.  I wasn't aware of the
existing variable, but I agree it's a better solution.  I'll look into
it.


Emacs: Crypto: How to get automatic encryption?

2012-01-17 Thread David Edmondson
On Mon, 16 Jan 2012 23:48:30 -0500, Antoine Beaupr?  
wrote:
> Jumping in here, I have modified the previously posted code here to
> provide me with a more complete solution.

This looks good. I'll switch over to using it.

> Code is attached. Obviously, those function names would change if they
> would be to integrate into notmuch. ;)

I wondered about pushing to have notmuch do this by default. In general
I like the idea, but it suffers if a recipient occasionally uses a mail
client that does not support decryption (phone, PDA, webmail, ...).
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/34a23311/attachment.pgp>


[PATCH v2 4/4] emacs: Use the new JSON reply format.

2012-01-17 Thread Adam Wolfe Gordon
Hi David,

Thanks for the review. A couple of comments inline:

On Tue, Jan 17, 2012 at 02:04, David Edmondson  wrote:
>> + ? ?(insert "\n")
>> + ? ?(set-buffer-modified-p nil)))
>
> Is this newline always required? Is it the cause of the spurious blank
> line down below?

This is the cause of the spurious blank line, but without it the tests
complain about missing a blank line at the end of the file.  There may
be a better way to deal with this - I'll experiment.

>> ?(defun notmuch-mua-reply (query-string  sender reply-all)
>> ...
>> + ? ? ?(insert (format "On %s, %s wrote:\n"
>> + ? ? ? ? ? ? ? ? ? (cdr (assq 'date original-headers))
>> + ? ? ? ? ? ? ? ? ? (cdr (assq 'from original-headers
>
> I wonder whether emacs should be regenerating this or not. I'm okay with
> it, but previous discussion was that it should remain the responsibility
> of the CLI.

I like this being generated in the MUA because then it can be
customized easily (e.g. in my later patch).  Of course, it would also
be possible to add this as a config option for the CLI and generate it
there, but it feels to me like if there's a line between notmuch and
the MUA, this belongs on the MUA side, especially in MUAs that are
formatting the reply themselves anyway.

I'm happy to hear more discussion on this, and will implement whatever
seems best.  I don't actually use the customization myself, it just
strikes me as a useful feature.


[PATCH] emacs: Improved printing support.

2012-01-17 Thread David Edmondson
On Mon, 16 Jan 2012 16:27:06 -0500, Aaron Ecay  wrote:
> > +;;
> 
> The above is just a stray comment line, right?

I tend to use them as spacers, but, sure.

> > +(defun notmuch-show-with-message-as-text (fn)
> > +  "Apply function `fn' to a text representation of the current
> > +message."
> 
> I think the docstring should say what agrs get passed to ?fn?.  Also,
> function arguments should be referred to with capital letters, and the
> first line should be a complete sentence.  I?d recommend ?Apply FN to
> (...the rest unchanged)? for brevity in the first line.
> 
> (For anyone who is curious, these and other conventions are documented
> in section D.6 of the Elisp manual.)

Will fix.
> > + (concat "Tags: "
> > + (mapconcat '(lambda (tag) tag) tags ", ") "\n")
> 
> #'identity instead of the lambda

/me slaps head. What was I thinking?

> > +(all (buffer-substring (notmuch-show-message-top)
> > +   (notmuch-show-message-bottom)))
> > +
> > +(file (make-temp-file "notmuch")))
> > +(with-temp-file file
> > +  (insert all)
> > +  (indent-rigidly (point-min) (point-max) (- depth))
> > +  ;; Remove the original header.
> > +  (goto-char (point-min))
> > +  (re-search-forward "^$" (point-max) nil)
> > +  (delete-region (point-min) (point))
> > +  (insert header))
> > +(funcall fn file (notmuch-show-get-message-properties))
> > +(delete-file file)))
> 
> Why does this function write to a file?  It seems that, of the print
> methods, two (ps-print and lpr) don?t use the file at all.  One
> (ps-print/evince) creates yet another file, without depending on the
> first.  The other muttprint functions do use the file.  So:
> - This function would be more general if it didn?t handle file-writing
>   itself, but rather let each consumer of text-ified messages handle
>   that if needed.
> - It would be cleaner if print backends that don?t crucially depend on
>   the existence of a file didn?t create one at all.  If muttprint can
>   accept a message on stdin (it looks from the source like it can; it
>   gives me some error message about Iconv Perl modules when I try to run
>   it, so I can?t be sure), maybe writing to a file isn?t necessary at
>   all.

I'll rework it, thanks for the review!
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/e855f75e/attachment-0001.pgp>


[PATCH v2 3/3] search: Support automatic tag exclusions

2012-01-17 Thread David Edmondson
On Mon, 16 Jan 2012 15:16:24 -0700, Jeremy Nickurak  
wrote:
> On Mon, Jan 16, 2012 at 12:28, Austin Clements  wrote:
> >> Having "deleted" and "spam" as default settings in the configuration
> >> file might be more reasonable.
> 
> If I read correctly:
> 
> 1) If no exclude options are in the config file, none should be used.

Yes.

> 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config

I might argue between 'should' and 'could', but the sense is correct.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/dfe82bc3/attachment.pgp>


[PATCH 1/1] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters

> > I wonder if the "problem" comes from me doing things in a non-lispy
> > fashion (I am completely new to lisp). Thus
> > notmuch-show-part-button-default-action is a variable that gets passed
> > around rather than a function.
> 
> Sorry, I should have looked at the bigger context in this patch.  I
> think Jameson was implying that notmuch-show-part-button-default
> should change to
> 
> (defun notmuch-show-part-button-default ( button)
>   (interactive)
>   (funcall notmuch-show-part-button-default-action button))
> 
> I would go one step further and say that each action should probably
> be a separate function.  That is, break notmuch-show-part-action into
> separate functions and simply invoke the appropriate function, rather
> than performing a fixed data dispatch.  This would be more flexible
> and Lispy.  It may be that your approach works out better, but I'd at
> least give this a shot.

I am happy to make that change. My original patch in the summer was more
like that:
id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com"

Is that more what you had in mind? (Only in broad terms: Obviously I
would need to add in the customization and default function etc). I
decided that I didn't like the code duplication (but I am completely new
to lisp) which is why I changed it for this submission.

Best wishes

Mark


how about message-citation-line-format (was: Re: [PATCH v2 5/4] emacs: Add customization for the first line of quotes.)

2012-01-17 Thread David Edmondson
On Tue, 17 Jan 2012 08:17:49 +0100, Gregor Zattler  wrote:
> Hi Adam, notmuch developers,
> * Adam Wolfe Gordon <awg+notmuch at xvx.ca> [16. Jan. 2012]:
> > Add a customization option, notmuch-mua-reply-quoth, which controls
> > the first line of the reply body (typically, "On %date%, %from% wrote:").
> > This allows users who like other styles or correspond in other languages
> > to set an appropriate line using any of the quoted message's headers.
> 
> I really missed this feature in notmuch.  There is already
> message-citation-line-format which is part of message mode or
> gnus and is not used in notmuch.  Wouldn't it be more consistent
> to reuse this?

If we're going to do it, this would be the right approach.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/6bffc31f/attachment.pgp>


[PATCH v2 4/4] emacs: Use the new JSON reply format.

2012-01-17 Thread David Edmondson
Much nicer now that it uses the mm stuff.

On Mon, 16 Jan 2012 11:13:23 -0700, Adam Wolfe Gordon <awg+notmuch at xvx.ca> 
wrote:
> +(defun find-parts (parts type)

Sorry for being a nuisance - this needs a name that indicates that it
relates to notmuch. How about `notmuch-parts-filter-by-type'?

> +  "Return a list of message parts with the given type"
> +  (delq nil (mapcar (lambda (part)
> +   (if (string= (cdr (assq 'content-type part)) type)
> +   (cdr (assq 'content part
> + parts)))

'(delq nil ...)' can more readably be implemented using something like:

   (loop for part in parts
 if (string= (cdr (assq 'content-type part)) type)
 collect (cdr (assq 'content part)))

(untested).

> +(defun notmuch-mua-insert-part-quoted (part)
> +  (save-restriction
> +(narrow-to-region (point) (point))
> +(insert part)
> +(goto-char (point-min))
> +(perform-replace "^" "> " nil t nil)

Narrowing to '(point) (point)' seems a bit weird and using
`perform-replace' is discouraged in programs. It would be more normal to
use a loop of `re-search-forward' and `replace-match' with a limit after
the insertion. Something like:

  (let ((start (point))
limit)
(insert part)
(setq limit (point))
(goto-char start)
(while (re-search-forward "^" limit t)
  (replace-match "> "))

...

(untested).

> +(insert "\n")
> +(set-buffer-modified-p nil)))

Is this newline always required? Is it the cause of the spurious blank
line down below?

> +(defun notmuch-mua-parse-html-part (part)
> +  (with-temp-buffer
> +(insert part)
> +(let ((handle (mm-make-handle (current-buffer) (list "text/html")))
> +   (end-of-orig (point-max)))
> +  (mm-display-part handle)
> +  (kill-region (point-min) end-of-orig)
> +  (fill-region (point-min) (point-max))
> +  (buffer-substring (point-min) (point-max)

`kill-region' will save content in the kill ring. Was that intended?
(Maybe `delete-region' instead?)

>  (defun notmuch-mua-reply (query-string  sender reply-all)
> ...
> +  (insert (format "On %s, %s wrote:\n"
> +   (cdr (assq 'date original-headers))
> +   (cdr (assq 'from original-headers

I wonder whether emacs should be regenerating this or not. I'm okay with
it, but previous discussion was that it should remain the responsibility
of the CLI.

> +  (if (null plain-parts)
> +   (mapc (lambda (part) (notmuch-mua-insert-part-quoted 
> (notmuch-mua-parse-html-part part))) html-parts)
> + (mapc (lambda (part) (notmuch-mua-insert-part-quoted part)) 
> plain-parts))

Flip the 'then' and 'else' clauses to get rid of the `null'?

> --- a/test/emacs
> +++ b/test/emacs
> @@ -270,6 +270,7 @@ Fcc: $(pwd)/mail/sent
>  --text follows this line--
>  On 01 Jan 2000 12:00:00 -, Notmuch Test Suite  notmuchmail.org> wrote:
>  > This is a test that messages are sent via SMTP
> +> 

It would be good if you could get rid of this trailing blank line.
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20120117/40c6bf84/attachment.pgp>


[PATCH] Start devel directory for developer tools and documentation.

2012-01-17 Thread David Bremner
From: David Bremner 

We had a lot of back and forth about the name of this directory, but
nothing very conclusive. In the end, I just chose "devel" just to move
on.
---
 RELEASING => devel/RELEASING |0
 TODO => devel/TODO   |0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename RELEASING => devel/RELEASING (100%)
 rename TODO => devel/TODO (100%)

diff --git a/RELEASING b/devel/RELEASING
similarity index 100%
rename from RELEASING
rename to devel/RELEASING
diff --git a/TODO b/devel/TODO
similarity index 100%
rename from TODO
rename to devel/TODO
-- 
1.7.8.3



  1   2   3   >